2 Read in data

european <- read_csv("01-cleaning_data_data/european_recoded.csv")
australian <- read_csv("01-cleaning_data_data/australian_recoded.csv")
dim(european)
[1] 209 117
dim(australian)
[1] 269 146
european$EU <- 1
australian$AU <- 1
all <- merge(european,australian,all = TRUE)
table(all$EU,all$AU,useNA = "always")
      
         1 <NA>
  1      0  209
  <NA> 269    0

2.1 Variables to describe dataset (can be different between contexts)

demographics_var <- c("Age","Gender","L1","speak.other.L2","study.other.L2","origins","year.studyL2","other5.other.ways","degree","roleL2.degree","study.year","prof","L2.VCE","uni1.year","Context")
l2School <- "\\.L2school$"
l2School_variables <- colnames(all)[grep(l2School,colnames(all))]
  • First language
#table(all$L1,all$Context) # too many levels - needs to be cleaned (ex tot number of languages?)
table(all$L1,useNA = "always")

         Afrikaans           Albanian            Burmese          Cantonese 
                 1                  2                  1                  4 
           Chinese           Croatian              Dutch            English 
                 7                  1                  1                201 
 English and Dutch             German German and English German and Turkish 
                 2                 77                  2                  1 
                 I         Indonesian            Italian           Japanese 
                 1                  1                 89                  1 
          Mandarin            Persian    Persian (Farsi)           Romanian 
                 5                  1                  1                  3 
           Russian             Sindhi             Slovak            Spanish 
                 2                  1                  1                  3 
           Turkish          Ukrainian               <NA> 
                 1                  1                 67 
ggplot(all,aes(x=L1,fill=Context)) + geom_bar() + coord_flip() + ggtitle("First Language") + labs(y="N. of participants",x="")+theme_bw()

#table(all$speak.other.L2,all$Context)
L2 <- data.frame(Freq=table(all$speak.other.L2)[order(table(all$speak.other.L2),decreasing = TRUE)],
                 L2=names(table(all$speak.other.L2))[order(table(all$speak.other.L2),decreasing = TRUE)]) # too many levels - needs to be cleaned (ex tot number of languages?)
head(L2)
  • origins
table(all$origins,useNA = "always")

  No  Yes <NA> 
 323   89   66 
table(all$year.studyL2)

                     0 years                   1- 3 years                    1-3 years 
                          69                           12                           11 
                   4-6 years First year of primary school                 Kindergarten 
                          61                           80                           30 
            Less than a year            more than 6 years                        Other 
                          27                           49                           72 
table(all$degree)

                    BA in Anglistik            BA in Nordamerikastudien 
                                 43                                   4 
                                HUM                             HUM.SCI 
                                129                                   6 
                                 LA      Lingue e letterature straniere 
                                 36                                  82 
Lingue, mercati e culture dell'Asia                                  QC 
                                 13                                   5 
                                SCI 
                                 86 
  • study.year in the European context is uni1.year in the Australian context
all$study.year[is.na(all$study.year)] <- all$uni1.year[is.na(all$study.year)]
#table(all$study.year)
all$study.year <- ifelse(all$study.year == "Already graduated after 5 semesters in March 2016, was interested in survery/study, sorry.","6th semester",all$study.year)
table(all$study.year)

      1st semester           1st year       2nd semester           2nd year 
                72                255                  5                 37 
      3rd semester           3rd year 3rd year of Master  4th year bachelor 
                 5                 20                  1                  8 
      5th semester       6th semester           7th year             Master 
                 2                  3                  1                  3 
  • proficiency
table(all$prof,useNA = "always")

          Advanced         Elementary       Intermediate Upper-intermediate 
                78                105                 84                146 
              <NA> 
                65 

3 Filter participants : keep only the ones that meet the inclusion criteria

all$study.year[is.na(all$study.year)] <- all$uni1.year[is.na(all$study.year)]
# Filter only subject that we want to include in the study
# names(table(all$study.year))[1] = 1st semester"
filtered <- subset(all, (study.year == "1st year") | (study.year == names(table(all$study.year))[1]))
#& year.studyL2 != "0 years"

3.1 Imputing degree based on Quality Comments provided in the questions

  • 5313976716 : SCI (wish to study science in the future)
  • 5359866545 : HUM.SCI (based on degree.other7)
  • 5375370122 : SCI (she wants to do science)
  • 5375376761 : HUM (she wants to do translation/reserach/teaching)
filtered$degree[filtered$Resp.ID %in% "5313976716"] <- "SCI"
filtered$degree[filtered$Resp.ID %in% "5359866545"] <- "HUM.SCI"
filtered$degree[filtered$Resp.ID %in% "5375370122"] <- "SCI"
filtered$degree[filtered$Resp.ID %in% "5375376761"] <- "HUM"
table(filtered$degree)

                    BA in Anglistik            BA in Nordamerikastudien 
                                 39                                   4 
                                HUM                             HUM.SCI 
                                 98                                   6 
                                 LA      Lingue e letterature straniere 
                                 27                                  78 
Lingue, mercati e culture dell'Asia                                 SCI 
                                 13                                  58 
kable(table(filtered$Context))


|Var1                 | Freq|
|:--------------------|----:|
|English in Germany   |   72|
|English in Italy     |   91|
|German in Australia  |   89|
|Italian in Australia |   75|
kable(table(filtered$year.studyL2,filtered$Context))


|                             | English in Germany| English in Italy| German in Australia| Italian in Australia|
|:----------------------------|------------------:|----------------:|-------------------:|--------------------:|
|0 years                      |                  0|                0|                  22|                   11|
|1- 3 years                   |                  0|                0|                   0|                    9|
|1-3 years                    |                  0|                0|                   7|                    0|
|4-6 years                    |                  0|                0|                  35|                   20|
|First year of primary school |                 17|               56|                   0|                    0|
|Kindergarten                 |                  6|               23|                   0|                    0|
|Less than a year             |                  0|                0|                  13|                    5|
|more than 6 years            |                  0|                0|                  11|                   30|
|Other                        |                 48|               12|                   0|                    0|
kable(table(filtered$year.studyL2,filtered$prof))


|                             | Advanced| Elementary| Intermediate| Upper-intermediate|
|:----------------------------|--------:|----------:|------------:|------------------:|
|0 years                      |        0|         32|            1|                  0|
|1- 3 years                   |        0|          4|            5|                  0|
|1-3 years                    |        0|          1|            3|                  3|
|4-6 years                    |        1|          9|           26|                 19|
|First year of primary school |       20|          1|            6|                 46|
|Kindergarten                 |        8|          1|            3|                 17|
|Less than a year             |        0|         11|            4|                  3|
|more than 6 years            |        2|          5|           16|                 18|
|Other                        |       33|          0|            5|                 22|
kable(table(filtered$year.studyL2,filtered$Context))


|                             | English in Germany| English in Italy| German in Australia| Italian in Australia|
|:----------------------------|------------------:|----------------:|-------------------:|--------------------:|
|0 years                      |                  0|                0|                  22|                   11|
|1- 3 years                   |                  0|                0|                   0|                    9|
|1-3 years                    |                  0|                0|                   7|                    0|
|4-6 years                    |                  0|                0|                  35|                   20|
|First year of primary school |                 17|               56|                   0|                    0|
|Kindergarten                 |                  6|               23|                   0|                    0|
|Less than a year             |                  0|                0|                  13|                    5|
|more than 6 years            |                  0|                0|                  11|                   30|
|Other                        |                 48|               12|                   0|                    0|

People that have studied 0 years L2 are just a small subset of the German in Australia and Italian in Australia context which means that by correcting for context we are not removing the effect of the 0 years. A way to remove the effect of the 0 years participants and not including too many variables could be to estimate the effect of 0 years vs all.

4 Define demographic variables

4.1 Need to check datasets with Rcihi (why do we have QC in L1? Am I using not the latest dataset?)

all <- filtered
demographics_var <- c("Age","Gender","L1","speak.other.L2","study.other.L2","origins","year.studyL2","other5.other.ways","degree","roleL2.degree","study.year","prof","L2.VCE","uni1.year","Context")
l2School <- "\\.L2school$"
l2School_variables <- colnames(all)[grep(l2School,colnames(all))]
ggplot(all,aes(x=L1,fill=Context)) + geom_bar() + coord_flip() + ggtitle("First Language") + labs(y="N. of participants",x="") + theme_bw()

table(all$L1,all$Context)
                    
                     English in Germany English in Italy German in Australia
  Afrikaans                           0                0                   1
  Albanian                            0                1                   0
  Cantonese                           0                0                   2
  Chinese                             0                2                   2
  Dutch                               1                0                   0
  English                             1                0                  75
  English and Dutch                   0                0                   2
  German                             64                0                   0
  German and English                  1                0                   1
  I                                   0                0                   0
  Indonesian                          0                0                   1
  Italian                             0               87                   0
  Japanese                            0                0                   1
  Mandarin                            0                0                   1
  Persian (Farsi)                     0                0                   1
  Romanian                            0                0                   1
  Russian                             2                0                   0
  Sindhi                              0                0                   1
  Spanish                             1                0                   0
  Turkish                             1                0                   0
  Ukrainian                           0                1                   0
                    
                     Italian in Australia
  Afrikaans                             0
  Albanian                              0
  Cantonese                             0
  Chinese                               0
  Dutch                                 0
  English                              73
  English and Dutch                     0
  German                                0
  German and English                    0
  I                                     1
  Indonesian                            0
  Italian                               0
  Japanese                              0
  Mandarin                              1
  Persian (Farsi)                       0
  Romanian                              0
  Russian                               0
  Sindhi                                0
  Spanish                               0
  Turkish                               0
  Ukrainian                             0
table(all$degree,all$L1)
                                     
                                      Afrikaans Albanian Cantonese Chinese Dutch English
  BA in Anglistik                             0        0         0       0     0       1
  BA in Nordamerikastudien                    0        0         0       0     0       0
  HUM                                         1        0         2       0     0      93
  HUM.SCI                                     0        0         0       0     0       6
  LA                                          0        0         0       0     1       0
  Lingue e letterature straniere              0        1         0       1     0       0
  Lingue, mercati e culture dell'Asia         0        0         0       1     0       0
  SCI                                         0        0         0       2     0      47
                                     
                                      English and Dutch German German and English  I
  BA in Anglistik                                     0     34                  1  0
  BA in Nordamerikastudien                            0      4                  0  0
  HUM                                                 1      0                  0  1
  HUM.SCI                                             0      0                  0  0
  LA                                                  0     25                  0  0
  Lingue e letterature straniere                      0      0                  0  0
  Lingue, mercati e culture dell'Asia                 0      0                  0  0
  SCI                                                 1      0                  1  0
                                     
                                      Indonesian Italian Japanese Mandarin
  BA in Anglistik                              0       0        0        0
  BA in Nordamerikastudien                     0       0        0        0
  HUM                                          0       0        0        0
  HUM.SCI                                      0       0        0        0
  LA                                           0       0        0        0
  Lingue e letterature straniere               0      75        0        0
  Lingue, mercati e culture dell'Asia          0      12        0        0
  SCI                                          1       0        1        2
                                     
                                      Persian (Farsi) Romanian Russian Sindhi Spanish
  BA in Anglistik                                   0        0       2      0       1
  BA in Nordamerikastudien                          0        0       0      0       0
  HUM                                               0        0       0      0       0
  HUM.SCI                                           0        0       0      0       0
  LA                                                0        0       0      0       0
  Lingue e letterature straniere                    0        0       0      0       0
  Lingue, mercati e culture dell'Asia               0        0       0      0       0
  SCI                                               1        1       0      1       0
                                     
                                      Turkish Ukrainian
  BA in Anglistik                           0         0
  BA in Nordamerikastudien                  0         0
  HUM                                       0         0
  HUM.SCI                                   0         0
  LA                                        1         0
  Lingue e letterature straniere            0         1
  Lingue, mercati e culture dell'Asia       0         0
  SCI                                       0         0
  • Check for L1 but we decided not to filter for it
#Filter by L1
nc <- names(table(all$Context))
table(all$Context)

  English in Germany     English in Italy  German in Australia Italian in Australia 
                  72                   91                   89                   75 
l1_filter <- all[(all$Context == nc[1] & (all$L1 == "German" | all$L1 == "German and English")) | 
                    (all$Context == nc[2] & (all$L1 == "Italian")) | 
                    (all$Context == nc[3] & (all$L1 == "English" | all$L1 == "English and Dutch" | all$L1 == "German and English")) |
                    (all$Context == nc[4] & (all$L1 == "English" | all$L1 == "English and Dutch" | all$L1 == "German and English")),]
#all <- l1_filter
# do not filter for L1
all <- all
# subset demographics
demo <- subset(all,select=c("Resp.ID",demographics_var,l2School_variables))
# Numeri finali
table(l1_filter$Context)

  English in Germany     English in Italy  German in Australia Italian in Australia 
                  65                   87                   78                   73 
table(all$Context)

  English in Germany     English in Italy  German in Australia Italian in Australia 
                  72                   91                   89                   75 
  • Filter missing value:
  • Filter participants who didn’t put the degree
  • we don’t care about speak.other.L2 and study.other.L2
missing_bySample <- rowSums(is.na(demo))
names(missing_bySample) <- demo$Resp.ID
missing_byVar <- colSums(is.na(demo))
names(missing_byVar) <- colnames(demo)
barplot(missing_bySample)

d <- data.frame(miss=missing_byVar)
d$varID <- rownames(d)
ggplot(data=d,aes(x=varID,y=miss)) + geom_bar(stat="identity") + theme_bw() +theme(axis.text.x = element_text(angle = 45, hjust = 1)) 

demo_missing <- demo %>% group_by(Context) %>% summarise(roleL2.degree_na = sum(is.na(roleL2.degree)),
                                                         L2.VCE_na = sum(is.na(L2.VCE)),
                                                         other5.other.ways_na=sum(is.na(other5.other.ways )),
                                                         uni1.year_na = sum(is.na(uni1.year)),
                                                         primary1.L2school_na=sum(is.na(primary1.L2school)),
                                                         CLS3.L2school_na = sum(is.na(CLS3.L2school)),
                                                         VSL4.L2school_na=sum(is.na(VSL4.L2school)),
                                                         degree = sum(is.na(degree)),
                                                         schooL2country5.L2school_na=sum(is.na(schooL2country5.L2school)))
# We do not filter for speak.other.L2 or study.other.L2
#demo[is.na(demo$speak.other.L2),]
# teniamo
#demo[is.na(demo$study.other.L2),]
missing_bySample[names(missing_bySample) == "5166861581"]
5166861581 
        10 
#demo[is.na(demo$year.studyL2),]
missing_bySample[names(missing_bySample) == "5378798787"]
5378798787 
         3 
# remove NA from degree
#table(demo$degree,useNA = "always")
# Remove people
all <- all[!is.na(all$degree),]

4.2 Stats about filtered dataset

kable(table(all$Context))


|Var1                 | Freq|
|:--------------------|----:|
|English in Germany   |   70|
|English in Italy     |   91|
|German in Australia  |   88|
|Italian in Australia |   74|
kable(table(all$study.year))


|Var1         | Freq|
|:------------|----:|
|1st semester |   70|
|1st year     |  253|
kable(table(all$year.studyL2))


|Var1                         | Freq|
|:----------------------------|----:|
|0 years                      |   33|
|1- 3 years                   |    9|
|1-3 years                    |    7|
|4-6 years                    |   53|
|First year of primary school |   73|
|Kindergarten                 |   29|
|Less than a year             |   18|
|more than 6 years            |   41|
|Other                        |   59|

4.3 Recoded demographic variables

recoded_dem_richi <- read_excel("02-descriptive_data/21 03 merged_filtered_imputedMedian_likertNumber.xlsx")

4.4 Write filtered and merged dataset

write.csv(all,file.path("02-descriptive_data/context-merged_filtered.csv"))

4.5 Descriptive plots and tables

all$speak.other.L2_binary <- ifelse(!is.na(all$speak.other.L2) & 
                                      !(all$speak.other.L2 %in% c("Yes","No")),"Yes",as.character(all$speak.other.L2))
kable(table(all$speak.other.L2_binary,all$Context,useNA = "always"))


|    | English in Germany| English in Italy| German in Australia| Italian in Australia| NA|
|:---|------------------:|----------------:|-------------------:|--------------------:|--:|
|No  |                 12|               24|                  52|                   53|  0|
|Yes |                 57|               67|                  36|                   20|  0|
|NA  |                  1|                0|                   0|                    1|  0|
  • Age
tabAge <- t(table(all$Age,all$Context))
ggdf <- data.frame(Age = rep(colnames(tabAge),each=4)[!(as.numeric(tabAge) == 0)],
  N.Participants = as.numeric(tabAge)[!(as.numeric(tabAge) == 0)],
  Context = rep(rownames(tabAge),times=3)[!(as.numeric(tabAge) == 0)])
ggplot(ggdf,aes(x=Age,y=N.Participants,fill=Context)) + geom_bar(position="dodge",colour="white",stat="identity")  + scale_y_continuous(breaks=seq(0,90,10),limits=c(0,90)) + theme_bw() + ggtitle("Participants by age")+
  geom_text(aes(label = N.Participants), hjust=0.5, vjust=-0.25, size = 2.5,position=position_dodge(width=0.9)) 

# add numbers on the bar
tabAge <- t(table(all$Gender,all$Context))
ggdf <- data.frame(Gender = rep(colnames(tabAge),each=4)[!(as.numeric(tabAge) == 0)],
  N.Participants = as.numeric(tabAge)[!(as.numeric(tabAge) == 0)],
  Context = rep(rownames(tabAge),times=3)[!(as.numeric(tabAge) == 0)])
ggplot(ggdf,aes(x=Gender,y=N.Participants,fill=Context)) + geom_bar(position="dodge",colour="white",stat="identity")  + labs(y="N participants") + scale_y_continuous(breaks=seq(0,90,10),limits=c(0,90)) + theme_bw() + ggtitle("Participants by gender")+  geom_text(aes(label = N.Participants), hjust=0.5, vjust=-0.25, size = 2.5,position=position_dodge(width=0.9)) 

# add numbers on the bar
tabAge <- t(table(all$origins,all$Context))
ggplot(all,aes(x=origins,fill=Context)) + geom_bar(position="dodge",colour="white") + ggtitle("Origins by context") + scale_y_continuous(breaks=seq(0,90,10),limits=c(0,90)) + theme_bw() + draw_grob(tableGrob(tabAge), x=2, y=60, width=0.3, height=0.4) + ggtitle("Participants by origins")

tabAge
                      
                       No Yes
  English in Germany   65   5
  English in Italy     90   1
  German in Australia  63  25
  Italian in Australia 36  38
  • proficiency
tabAge <- t(table(all$prof,all$Context))
ggplot(all,aes(x=Context,fill=prof)) + geom_bar(position="dodge",colour="white") + ggtitle("Proficiency by context") + scale_y_continuous(breaks=seq(0,90,10),limits=c(0,90)) + theme_bw() + draw_grob(tableGrob(tabAge), x=2, y=80, width=0.3, height=0.4)

tabAge
                      
                       Advanced Elementary Intermediate Upper-intermediate
  English in Germany         38          0            5                 27
  English in Italy           23          2            9                 57
  German in Australia         4         32           25                 27
  Italian in Australia        0         29           29                 16
  • L2.VCE
tabAge <- t(table(all[all$Context != "English in Germany" & all$Context != "English in Italy","L2.VCE"],all[all$Context != "English in Germany" & all$Context != "English in Italy",'Context'],useNA = "always"))
tabAge <- tabAge[-3,]
ggplot(all[all$Context != "English in Germany" & all$Context != "English in Italy",],aes(x=Context,fill=L2.VCE)) + geom_bar(position="dodge",colour="white") + ggtitle("L2.VCE by context") + scale_y_continuous(breaks=seq(0,90,10),limits=c(0,90)) + theme_bw() + draw_grob(tableGrob(tabAge), x=2, y=80, width=0.3, height=0.4)

  • da mettere a posto con Richi
# year study L2
table(all$year.studyL2,all$other.year.studyL2.richi)
                              
                               BILINGUAL FIRST.YEAR.SECONDARY FOURTH.YEAR.PRIMARY
  0 years                              0                    0                   0
  1- 3 years                           0                    0                   0
  1-3 years                            0                    0                   0
  4-6 years                            0                    0                   0
  First year of primary school         0                    0                   0
  Kindergarten                         0                    0                   0
  Less than a year                     0                    0                   0
  more than 6 years                    0                    0                   0
  Other                                4                   10                   5
                              
                               LOWER.SECONDARY PERSONAL SECOND.YEAR.PRIMARY
  0 years                                    0        0                   0
  1- 3 years                                 0        0                   0
  1-3 years                                  0        0                   0
  4-6 years                                  0        0                   0
  First year of primary school               0        0                   0
  Kindergarten                               0        0                   0
  Less than a year                           0        0                   0
  more than 6 years                          0        0                   0
  Other                                      4        2                   2
                              
                               SECOND.YEAR.SECONDARY THIRD.YEAR.PRIMARY
  0 years                                          0                  0
  1- 3 years                                       0                  0
  1-3 years                                        0                  0
  4-6 years                                        0                  0
  First year of primary school                     0                  0
  Kindergarten                                     0                  0
  Less than a year                                 0                  0
  more than 6 years                                0                  0
  Other                                            2                 28
all$year.studyL2 <- ifelse(all$year.studyL2 == "Other",all$other.year.studyL2.richi,all$year.studyL2 )
# European context
ggplot(all[all$Context == "English in Germany" | all$Context == "English in Italy",],aes(x=degree,fill=year.studyL2)) + geom_bar(position="dodge",colour="white") + theme_bw() + ggtitle("Degree by study year L2, by Context") +  facet_grid(~Context,scales="free") + theme(axis.text.x = element_text(angle = 45, hjust = 1)) + labs(y = "N participants", x = "degree")

  • Degree of enrolment
# Australian context
tabAge <- t(table(all[all$Context == "Italian in Australia" | all$Context == "German in Australia",'degree'],all[all$Context == "Italian in Australia" | all$Context == "German in Australia",'Context']))
ggplot(all[all$Context == "Italian in Australia" | all$Context == "German in Australia",],aes(x=Context,fill=degree)) + geom_bar(position="dodge",colour="white") + theme_bw() + ggtitle("Degree in Australian Contexts") + draw_grob(tableGrob(tabAge), x=1., y=40, width=0.3, height=0.4)

tabAge
                      
                       HUM HUM.SCI SCI
  German in Australia   48       4  36
  Italian in Australia  50       2  22
# Australian context
tabAge <- t(table(all[all$Context == "English in Italy" | all$Context == "English in Germany",'degree'],all[all$Context == "English in Italy" | all$Context == "English in Germany",'Context']))
ggplot(all[all$Context == "English in Italy" | all$Context == "English in Germany",],aes(x=Context,fill=degree)) + geom_bar(position="dodge",colour="white") + theme_bw() + ggtitle("Degree in European Contexts")

tabAge
                    
                     BA in Anglistik BA in Nordamerikastudien LA
  English in Germany              39                        4 27
  English in Italy                 0                        0  0
                    
                     Lingue e letterature straniere Lingue, mercati e culture dell'Asia
  English in Germany                              0                                   0
  English in Italy                               78                                  13

5 Australian context spcific variables

kable(table(all$reconnect.comm,all$Context))


|                  | English in Germany| English in Italy| German in Australia| Italian in Australia|
|:-----------------|------------------:|----------------:|-------------------:|--------------------:|
|Agree             |                  0|                0|                   8|                   11|
|Disagree          |                  0|                0|                  35|                   14|
|Not sure          |                  0|                0|                   3|                    4|
|Strongly agree    |                  0|                0|                  12|                   28|
|Strongly disagree |                  0|                0|                  30|                   17|
kable(table(all$speakersmelb.comm,all$Context))


|                  | English in Germany| English in Italy| German in Australia| Italian in Australia|
|:-----------------|------------------:|----------------:|-------------------:|--------------------:|
|Agree             |                  0|                0|                  44|                   41|
|Disagree          |                  0|                0|                   6|                    2|
|Not sure          |                  0|                0|                  25|                   12|
|Strongly agree    |                  0|                0|                  12|                   19|
|Strongly disagree |                  0|                0|                   1|                    0|
kable(table(all$comecloser.comm,all$Context))


|                  | English in Germany| English in Italy| German in Australia| Italian in Australia|
|:-----------------|------------------:|----------------:|-------------------:|--------------------:|
|Agree             |                  0|                0|                  21|                   34|
|Disagree          |                  0|                0|                  16|                    6|
|Not sure          |                  0|                0|                  43|                   17|
|Strongly agree    |                  0|                0|                   6|                   17|
|Strongly disagree |                  0|                0|                   2|                    0|

6 Likert scales

  • Convert Likert scales to numbers
convertToNumber <- function(column){
  column <- factor(column,levels = c("Strongly disagree","Disagree","Not sure","Agree","Strongly agree"))
  column_number <- as.numeric(column)
  return(column_number)
}
table(all$Context)

  English in Germany     English in Italy  German in Australia Italian in Australia 
                  70                   91                   88                   74 
table(all$study.year)

1st semester     1st year 
          70          253 
convert_likert <- data.frame(apply(subset(all,select=likert_variables_all),2,convertToNumber))
colnames(convert_likert) <- paste0(colnames(convert_likert),"1")
likert_variables1 <- paste0(likert_variables_all,"1")
# join the converted variables to the filtered dataset
filtered_conv <- cbind(all,convert_likert)
table(filtered_conv[,likert_variables_all[4]],filtered_conv[,likert_variables1[4]],useNA = "always")
                   
                      1   2   3   4   5 <NA>
  Agree               0   0   0 121   0    0
  Disagree            0  10   0   0   0    0
  Not sure            0   0  39   0   0    0
  Strongly agree      0   0   0   0 152    0
  Strongly disagree   1   0   0   0   0    0
  <NA>                0   0   0   0   0    0
write.csv(filtered_conv,"02-descriptive_data/merged_filtered_likertNumber.csv",row.names = FALSE)

6.1 Impute missing values - Using median values

The missing values appears to be at random and there are max two missing values in one variable (see plots below). In order not to loose 12 participants while doing the factor analysis across contexts it is preferable to impute the 12 missing values.

all <- filtered_conv
# Items to use for factor analysis : items shared between contexts
# items to be used for the FA
usable_items <- likert_variables1[!(likert_variables1 %in% c("necessity1","educated1","reconnect.comm1", "speakersmelb.comm1", "comecloser.comm1"))]
rownames(all) <- all$Resp.ID
usable_data_context <- all[,c(usable_items,"Context")]
dat_noNA <- usable_data_context[rowSums(is.na(usable_data_context)) == 0,]
all_noNA <- all[rowSums(is.na(usable_data_context)) == 0,]
table(rowSums(is.na(usable_data_context)))

  0   1 
311  12 
# Participants with NA to remove
table(rowSums(is.na(usable_data_context)),usable_data_context$Context,useNA = "always")
      
       English in Germany English in Italy German in Australia Italian in Australia <NA>
  0                    70               85                  87                   69    0
  1                     0                6                   1                    5    0
  <NA>                  0                0                   0                    0    0
# Variable missing values
table(colSums(is.na(usable_data_context)))

 0  1  2 
19 10  1 
table(rowSums(is.na(usable_data_context)),usable_data_context$Context,useNA = "always")
      
       English in Germany English in Italy German in Australia Italian in Australia <NA>
  0                    70               85                  87                   69    0
  1                     0                6                   1                    5    0
  <NA>                  0                0                   0                    0    0
# check what to use to impute
# have a look at the distribution of missing values
library(mice)
Loading required package: lattice

Attaching package: ‘mice’

The following object is masked from ‘package:tidyr’:

    complete

The following objects are masked from ‘package:base’:

    cbind, rbind
library(VIM)
Loading required package: colorspace
Loading required package: grid
Loading required package: data.table
data.table 1.11.4  Latest news: http://r-datatable.com

Attaching package: ‘data.table’

The following objects are masked from ‘package:reshape2’:

    dcast, melt

The following objects are masked from ‘package:dplyr’:

    between, first, last

The following object is masked from ‘package:purrr’:

    transpose

VIM is ready to use. 
 Since version 4.0.0 the GUI is in its own package VIMGUI.

          Please use the package to use the new (and old) GUI.

Suggestions and bug-reports can be submitted at: https://github.com/alexkowa/VIM/issues

Attaching package: ‘VIM’

The following object is masked from ‘package:datasets’:

    sleep
mice_plot <- aggr(usable_data_context[,usable_items], col=c('navyblue','yellow'),
                    numbers=TRUE, sortVars=TRUE,
                    labels=names(usable_data_context[,usable_items]), cex.axis=.4,
                    gap=1, ylab=c("Missing data","Pattern"),cex.numbers=0.5)

 Variables sorted by number of missings: 

# Imputing using median
library(Hmisc)
Loading required package: survival
Loading required package: Formula

Attaching package: ‘Hmisc’

The following object is masked from ‘package:sjmisc’:

    %nin%

The following object is masked from ‘package:psych’:

    describe

The following objects are masked from ‘package:dplyr’:

    src, summarize

The following objects are masked from ‘package:base’:

    format.pval, units
imputedMedian <- usable_data_context
imputedMedian$globalaccess.post1 <- with(imputedMedian[,usable_items], impute(globalaccess.post1, median))
imputedMedian$citizen.post1 <- with(imputedMedian[,usable_items], impute(citizen.post1, median))
imputedMedian$money.instru1 <- with(imputedMedian[,usable_items], impute(money.instru1, median))
imputedMedian$knowledge.instru1 <- with(imputedMedian[,usable_items], impute(knowledge.instru1, median))
imputedMedian$life.intr1 <- with(imputedMedian[,usable_items], impute(life.intr1, median))
imputedMedian$time.integr1 <- with(imputedMedian[,usable_items], impute(time.integr1, median))
imputedMedian$expect.ought1 <- with(imputedMedian[,usable_items], impute(expect.ought1, median))
imputedMedian$job.instru1 <- with(imputedMedian[,usable_items], impute(job.instru1, median))
imputedMedian$career.instru1 <- with(imputedMedian[,usable_items], impute(career.instru1, median))
imputedMedian$meeting.integr1 <- with(imputedMedian[,usable_items], impute(meeting.integr1, median))
imputedMedian$interact.post1 <- with(imputedMedian[,usable_items], impute(interact.post1, median))
# check before after
table(imputedMedian$time.integr1)

  2   3   4   5 
  3  21  95 204 
table(usable_data_context$time.integr1)

  2   3   4   5 
  3  21  95 202 
table(imputedMedian$life.intr1)

  1   2   3   4   5 
  8  79  81 117  38 
table(usable_data_context$life.intr1)

  1   2   3   4   5 
  8  79  80 117  38 
table(imputedMedian$knowledge.instru1)

  1   2   3   4   5 
  1   2  29 189 102 
table(usable_data_context$knowledge.instru1)

  1   2   3   4   5 
  1   2  29 188 102 
table(imputedMedian$money.instru1)

  1   2   3   4   5 
  3  38 179  84  19 
table(usable_data_context$money.instru1)

  1   2   3   4   5 
  3  38 178  84  19 
table(imputedMedian$citizen.post1)

  1   2   3   4   5 
  3  22  75 148  75 
table(usable_data_context$citizen.post1)

  1   2   3   4   5 
  3  22  75 147  75 
table(imputedMedian$globalaccess.post1)

  1   2   3   4   5 
  1   3  20 159 140 
table(usable_data_context$globalaccess.post1)

  1   2   3   4   5 
  1   3  20 158 140 
table(imputedMedian$expect.ought1)

  1   2   3   4   5 
126 142  30  21   4 
table(usable_data_context$expect.ought1)

  1   2   3   4   5 
126 141  30  21   4 
table(imputedMedian$job.instru1)

  2   3   4   5 
 13 103 133  74 
table(usable_data_context$job.instru1)

  2   3   4   5 
 13 103 132  74 
table(imputedMedian$career.instru1)

  1   2   3   4   5 
  1   1  63 131 127 
table(usable_data_context$career.instru1)

  1   2   3   4   5 
  1   1  63 130 127 
table(imputedMedian$meeting.integr1)

  2   3   4   5 
  1  10 121 191 
table(usable_data_context$meeting.integr1)

  2   3   4   5 
  1  10 121 190 
table(imputedMedian$interact.post1)

  2   3   4   5 
  1  19 140 163 
table(usable_data_context$interact.post1)

  2   3   4   5 
  1  19 140 162 
  • Substitute imputed data for the common variables to be used in the Factor Analysis
all <- all[,!(colnames(all) %in% usable_items)]
imputedMedian$Context <- NULL
sum(!(colnames(imputedMedian) %in% usable_items))
[1] 0
all <- cbind(all,imputedMedian[match(rownames(imputedMedian),all$Resp.ID),])

Add some updates that Richi did in Date 7th June 2018

> Other_ways_and_degree_role_with_respondent_IDs <- read_excel("Other-ways-and-degree-role-with-respondent-IDs.xlsx")
> sum(Other_ways_and_degree_role_with_respondent_IDs$Resp.ID != Other_ways_and_degree_role_with_respondent_IDs$Resp.ID__1)
> # to replace 
> # match for the NA degree.role
> 
> match_updates <- match(all$Resp.ID,Other_ways_and_degree_role_with_respondent_IDs$Resp.ID)
> all$private.lessons1.other.ways[match_updates] <- Other_ways_and_degree_role_with_respondent_IDs$private.lessons1.other.ways
> all$study.holiday2.other.ways[match_updates] <- Other_ways_and_degree_role_with_respondent_IDs$study.holiday2.other.ways
> all$year.sem.abroad3.other.ways[match_updates] <- Other_ways_and_degree_role_with_respondent_IDs$year.sem.abroad3.other.ways
> all$online.course4.other.ways[match_updates] <- Other_ways_and_degree_role_with_respondent_IDs$online.course4.other.ways
> all$other5.other.ways[match_updates] <- Other_ways_and_degree_role_with_respondent_IDs$other5.other.ways
> all$degree.role[match_updates] <- Other_ways_and_degree_role_with_respondent_IDs$degree.role

6.2 Save imputed data

write.csv(all,"02-descriptive_data/merged_filtered_imputedMedian_likertNumber.csv",row.names = FALSE)

7 Barplot of likert variables

all_melt <- melt(all,id.vars = c("Resp.ID","Gender","Age","prof","Context","study.year"),
                        measure.vars = likert_variables1)
attributes are not identical across measure variables; they will be dropped
all_melt$value <- factor(all_melt$value,levels=c(1,2,3,4,5),labels=c("Strongly disagree","Disagree","Not sure","Agree","Strongly agree"))
# dim(all_melt)
# 323*length(likert_variables1)
all_melt <- all_melt %>% separate(variable,into=c("item","type"),sep="\\.",remove=FALSE)
Expected 2 pieces. Missing pieces filled with `NA` in 646 rows [9368, 9369, 9370, 9371, 9372, 9373, 9374, 9375, 9376, 9377, 9378, 9379, 9380, 9381, 9382, 9383, 9384, 9385, 9386, 9387, ...].
ggplot(all_melt,aes(x=variable,fill=value)) + geom_bar(position = "stack",colour="black") + 
  facet_grid(Context~type,scales = "free")+theme(axis.text.x = element_text(angle = 45, hjust = 1),axis.text=element_text(size=8)) + ggtitle("Filtered dataset") + scale_fill_manual(values=c("#ca0020","#f4a582","#ffffbf","#abd9e9","#2c7bb6","grey"))

filt_sum <- all_melt %>% group_by(Context,variable,type,value) %>% dplyr::summarise(Ngroup=length(value))
ggplot(filt_sum,aes(x=value,y=Ngroup,colour=Context,group=interaction(variable, Context))) + geom_line() + geom_point() + facet_wrap(~type,scales = "free")+theme(axis.text.x = element_text(angle = 45, hjust = 1))

7.1 Barplot of Educated and Necessity in the Australian and European Contexts

  • Educated
# add numbers on the bar
educated <- all[all$Context %in% c("German in Australia","Italian in Australia"),]
table(educated$educated1,educated$Context,useNA="always")
      
       German in Australia Italian in Australia <NA>
  1                     11                    9    0
  2                     25                   24    0
  3                     12                   13    0
  4                     29                   18    0
  5                     11                   10    0
  <NA>                   0                    0    0
educated$educated1 <- factor(educated$educated1,levels = c(1,2,3,4,5),labels=c("Strongly disagree","Disagree","Not sure","Agree","Strongly agree")) 
tabEdu <- t(table(educated$educated1,educated$Context))
ggdf <- data.frame(Educated = rep(colnames(tabEdu),each=2),
  N.Participants = as.numeric(tabEdu),
  Context = rep(rownames(tabEdu),times=5))
ggplot(ggdf,aes(x=Educated,y=N.Participants,fill=Context)) + geom_bar(position="dodge",colour="white",stat="identity")  + labs(y="N participants") + scale_y_continuous(breaks=seq(0,35,10),limits=c(0,35)) + theme_bw() + ggtitle("Educated by Context")+  geom_text(aes(label = N.Participants), hjust=0.5, vjust=-0.25, size = 2.5,position=position_dodge(width=0.9)) 

ggplot(ggdf,aes(x=Context,y=N.Participants,fill=Educated)) + geom_bar(position="dodge",colour="white",stat="identity")  + labs(y="N participants") + scale_y_continuous(breaks=seq(0,35,10),limits=c(0,35)) + theme_bw() + ggtitle("Educated by Context")+  geom_text(aes(label = N.Participants), hjust=0.5, vjust=-0.25, size = 2.5,position=position_dodge(width=0.9)) 

  • Necessity
# add numbers on the bar
necessity <- all[all$Context %in% c("English in Germany","English in Italy"),]
table(necessity$necessity1,necessity$Context,useNA="always")
      
       English in Germany English in Italy <NA>
  1                     1               12    0
  2                     7               16    0
  3                    13                6    0
  4                    32               36    0
  5                    16               20    0
  <NA>                  1                1    0
necessity$necessity1 <- factor(necessity$necessity1,levels = c(1,2,3,4,5),labels=c("Strongly disagree","Disagree","Not sure","Agree","Strongly agree")) 
tabNec <- t(table(necessity$necessity1,necessity$Context,useNA = "always"))[-3,]
ggdf <- data.frame(Necessity = rep(colnames(tabNec),each=2),
  N.Participants = as.numeric(tabNec),
  Context = rep(rownames(tabNec),times=6))
ggplot(ggdf,aes(x=Necessity,y=N.Participants,fill=Context)) + geom_bar(position="dodge",colour="white",stat="identity")  + labs(y="N participants") + scale_y_continuous(breaks=seq(0,40,10),limits=c(0,40)) + theme_bw() + ggtitle("Necessity by Context")+  geom_text(aes(label = N.Participants), hjust=0.5, vjust=-0.25, size = 2.5,position=position_dodge(width=0.9)) 

ggplot(ggdf,aes(x=Context,y=N.Participants,fill=Necessity)) + geom_bar(position="dodge",colour="white",stat="identity")  + labs(y="N participants") + scale_y_continuous(breaks=seq(0,35,10),limits=c(0,35)) + theme_bw() + ggtitle("Necessity by Context")+  geom_text(aes(label = N.Participants), hjust=0.5, vjust=-0.25, size = 2.5,position=position_dodge(width=0.9)) 

8 Correlation plot of items by context

8.1 Italian in Australia

cov <- cor(filtered_conv[filtered_conv$Context == "Italian in Australia",likert_variables1[!(likert_variables1 %in% "necessity1")]],method = "pearson",use="pairwise.complete.obs")
data_cor_ita_in_au <- data.frame(cor_ita_in_au=cov[lower.tri(cov, diag = TRUE)],
                var1 = rownames(cov)[unlist(t(mapply(":", 1:nrow(cov), nrow(cov)))[1,])],
                var2 = rep(colnames(cov),times=rev(seq(nrow(cov):1))))
row_infos <- data.frame(Variables=sapply(strsplit(colnames(cov),split="\\."),function(x) x[2]))
row_infos$Variables <- as.character(row_infos$Variables)
rownames(row_infos) <- rownames(cov)
row_infos$Variables[which(is.na(row_infos$Variables))] <- c("educated")
row_infos <- row_infos[order(row_infos$Variables),,drop=FALSE]
ann_col_wide <- data.frame(Variable=unique(row_infos$Variables))
ann_colors_wide <- list(Variables=c(comm1="#bd0026",educated="#b35806", id1="#f6e8c3",instru1="#35978f",integr1="#386cb0",intr1="#ffff99",ought1="grey",post1="black",prof1="pink"))
#pheatmap(cov, main = "Italian in Australia",annotation_names_row = FALSE,cluster_cols=TRUE,cluster_rows=TRUE,annotation_col = row_infos[,1,drop=FALSE], annotation_row = row_infos[,1,drop=FALSE],  annotation_colors = ann_colors_wide,breaks=seq(-1,1,0.2),col=c("#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#f7f7f7","#d1e5f0","#92c5de","#4393c3","#2166ac","#053061"),show_colnames = FALSE,width = 7,height = 7)
###################
diag(cov) <- NA
pheatmap(cov, main = "Italian in Australia",annotation_names_row = FALSE,cluster_cols=TRUE,cluster_rows=TRUE,annotation_col = row_infos[,1,drop=FALSE], annotation_row = row_infos[,1,drop=FALSE]
,  annotation_colors = ann_colors_wide,show_colnames = FALSE,breaks = seq(-0.6,0.7,length.out = 50),width = 7,height = 7,color=colorRampPalette(brewer.pal(n = 7, name = "RdBu"))(50))

cov_ItaAus <- cov

8.2 German in Australia

cov <- cor(filtered_conv[filtered_conv$Context == "German in Australia",likert_variables1[!(likert_variables1 %in% "necessity1")]],method = "pearson",use="pairwise.complete.obs")
data_cor_germ_in_au <- data.frame(cor_germ_in_au=cov[lower.tri(cov, diag = TRUE)],
                var1 = rownames(cov)[unlist(t(mapply(":", 1:nrow(cov), nrow(cov)))[1,])],
                var2 = rep(colnames(cov),times=rev(seq(nrow(cov):1))))
row_infos <- data.frame(Variables=sapply(strsplit(colnames(cov),split="\\."),function(x) x[2]))
row_infos$Variables <- as.character(row_infos$Variables)
rownames(row_infos) <- rownames(cov)
row_infos$Variables[which(is.na(row_infos$Variables))] <- c("educated")
row_infos <- row_infos[order(row_infos$Variables),,drop=FALSE]
ann_col_wide <- data.frame(Variable=unique(row_infos$Variables))
ann_colors_wide <- list(Variables=c(comm1="#bd0026",educated="#b35806", id1="#f6e8c3",instru1="#35978f",integr1="#386cb0",intr1="#ffff99",ought1="grey",post1="black",prof1="pink"))
diag(cov) <- NA
pheatmap(cov, main = "German in Australia",annotation_names_row = FALSE,cluster_cols=TRUE,cluster_rows=TRUE,annotation_col = row_infos[,1,drop=FALSE], annotation_row = row_infos[,1,drop=FALSE]
,  annotation_colors = ann_colors_wide,show_colnames = FALSE,breaks = seq(-0.6,0.7,length.out = 50),width = 7,height = 7,color=colorRampPalette(brewer.pal(n = 7, name = "RdBu"))(50))

# 
cov_GermAus <- cov

8.3 English in Germany

cov <- cor(filtered_conv[filtered_conv$Context == "English in Germany",likert_variables1[!(likert_variables1 %in% c("reconnect.comm1",    "speakersmelb.comm1","comecloser.comm1","educated1"))]],method = "pearson",use="pairwise.complete.obs")
data_cor_eng_in_germ <- data.frame(cor_eng_in_germ=cov[lower.tri(cov, diag = TRUE)],
                var1 = rownames(cov)[unlist(t(mapply(":", 1:nrow(cov), nrow(cov)))[1,])],
                var2 = rep(colnames(cov),times=rev(seq(nrow(cov):1))))
row_infos <- data.frame(Variables=sapply(strsplit(colnames(cov),split="\\."),function(x) x[2]))
row_infos$Variables <- as.character(row_infos$Variables)
rownames(row_infos) <- rownames(cov)
row_infos$Variables[which(is.na(row_infos$Variables))] <- c("necessity")
row_infos <- row_infos[order(row_infos$Variables),,drop=FALSE]
ann_col_wide <- data.frame(Variable=unique(row_infos$Variables))
ann_colors_wide <- list(Variables=c(id1="#f6e8c3",necessity="#b35806",instru1="#35978f",integr1="#386cb0",intr1="#ffff99",ought1="grey",post1="black",prof1="pink"))
diag(cov) <- NA
pheatmap(cov, main = "English in Germany",annotation_names_row = FALSE,cluster_cols=TRUE,cluster_rows=TRUE,annotation_col = row_infos[,1,drop=FALSE], annotation_row = row_infos[,1,drop=FALSE]
,  annotation_colors = ann_colors_wide,show_colnames = FALSE,breaks = seq(-0.6,0.7,length.out = 50),width = 7,height = 7,color=colorRampPalette(brewer.pal(n = 7, name = "RdBu"))(50))

cov_EngGerm <- cov

8.4 English in Italy

cov <- cor(filtered_conv[filtered_conv$Context == "English in Italy",likert_variables1[!(likert_variables1 %in% c("reconnect.comm1","speakersmelb.comm1","comecloser.comm1","educated1"))]],method = "pearson",use="pairwise.complete.obs")
data_cor_eng_in_ita <- data.frame(cor_eng_in_ita=cov[lower.tri(cov, diag = TRUE)],
                var1 = rownames(cov)[unlist(t(mapply(":", 1:nrow(cov), nrow(cov)))[1,])],
                var2 = rep(colnames(cov),times=rev(seq(nrow(cov):1))))
row_infos <- data.frame(Variables=sapply(strsplit(colnames(cov),split="\\."),function(x) x[2]))
row_infos$Variables <- as.character(row_infos$Variables)
rownames(row_infos) <- rownames(cov)
row_infos$Variables[which(is.na(row_infos$Variables))] <- "necessity"
row_infos <- row_infos[order(row_infos$Variables),,drop=FALSE]
ann_col_wide <- data.frame(Variable=unique(row_infos$Variables))
ann_colors_wide <- list(Variables=c(comm1="#bd0026",necessity="#b35806", id1="#f6e8c3",instru1="#35978f",integr1="#386cb0",intr1="#ffff99",ought1="grey",post1="black",prof1="pink"))
diag(cov) <- NA
pheatmap(cov, main = "English in Italy",annotation_names_row = FALSE,cluster_cols=TRUE,cluster_rows=TRUE,annotation_col = row_infos[,1,drop=FALSE], annotation_row = row_infos[,1,drop=FALSE]
,  annotation_colors = ann_colors_wide,show_colnames = FALSE,breaks = seq(-0.6,0.7,length.out = 50),width = 7,height = 7,color=colorRampPalette(brewer.pal(n = 7, name = "RdBu"))(50))

# 
cov_EngIta <- cov

8.5 Correlation between correlation in the different contexts

We will perform an exploratory FA combining all the contexts together. This means that we are assuming that the correlation between items across context has the same direction (does not happen that cor(item1,item2)_context1 > 0 and cor(item1,item2)_context2 < 0).

sum(rownames(common_ItaAus) != colnames(common_ItaAus))
[1] 0

8.6 All context together

cov <- cor(filtered_conv[,likert_variables1],method = "pearson",use="pairwise.complete.obs")

row_infos <- data.frame(Variables=sapply(strsplit(colnames(cov),split="\\."),function(x) x[2]))
row_infos$Variables <- as.character(row_infos$Variables)
rownames(row_infos) <- rownames(cov)
row_infos$Variables[which(is.na(row_infos$Variables))] <- c("necessity","educated")
row_infos <- row_infos[order(row_infos$Variables),,drop=FALSE]

ann_col_wide <- data.frame(Variable=unique(row_infos$Variables))
ann_colors_wide <- list(Variables=c(comm1="#bd0026",educated="orange", id1="#f6e8c3",instru1="#35978f",necessity="#b35806",integr1="#386cb0",intr1="#ffff99",ought1="grey",post1="black",prof1="pink"))

diag(cov) <- NA
pheatmap(cov, main = "All Contexts",annotation_names_row = FALSE,cluster_cols=TRUE,cluster_rows=TRUE,annotation_col = row_infos[,1,drop=FALSE], annotation_row = row_infos[,1,drop=FALSE]
,  annotation_colors = ann_colors_wide,show_colnames = FALSE,breaks = seq(-0.6,0.7,length.out = 50),width = 7,height = 7,color=colorRampPalette(brewer.pal(n = 7, name = "RdBu"))(50))

8.7 Compare correlations

combine_cor2$variable <- ifelse(is.na(combine_cor2$variable),combine_cor2$item,combine_cor2$variable)
Error in `$<-.data.frame`(`*tmp*`, variable, value = logical(0)) : 
  replacement has 0 rows, data has 591

9 Evaluate internal consistency of known constructs with alpha

sets <- list(id.var=likert_variables1[grep("\\.id1$",likert_variables1)],
             ought.var=likert_variables1[grep("\\.ought1$",likert_variables1)],
             intr.var=likert_variables1[grep("\\.intr1$",likert_variables1)],
             instru.var=likert_variables1[grep("\\.instru1$",likert_variables1)],
             integr1.var=likert_variables1[grep("\\.integr1$",likert_variables1)],
             prof.var=likert_variables1[grep("\\.prof1$",likert_variables1)],
             post.var=likert_variables1[grep("\\.post1$",likert_variables1)],
             comm.var=likert_variables1[grep("\\.comm1$",likert_variables1)])
              

get_alpha <- function(dataMot,
                      var=sets$id.var){
  var_alpha <- alpha(dataMot[,var])
  dataf <- data.frame(alpha=var_alpha$total,
                    drop = var_alpha$alpha.drop)
  rownames(dataf) <- rownames(var_alpha$alpha.drop)
  return(dataf)
}

# "Italian in Australia"
ita_in_au <- do.call(rbind,lapply(sets,function(x) {
  get_alpha(data=filtered_conv[filtered_conv$Context == "Italian in Australia",],
                      var=x)}))
ita_in_au$var <- sapply(strsplit(rownames(ita_in_au),split="\\."),function(x) x[1]) 
ita_in_au$var.full <- sapply(strsplit(rownames(ita_in_au),split="\\."),function(x) x[3]) 
ita_in_au$Context <- "Italian in Australia"
rownames(ita_in_au) <- NULL

# "German in Australia"
germ_in_au <- do.call(rbind,lapply(sets,function(x) {
  get_alpha(data=filtered_conv[filtered_conv$Context == "German in Australia",],
                      var=x)}))
germ_in_au$var <- sapply(strsplit(rownames(germ_in_au),split="\\."),function(x) x[1]) 
germ_in_au$var.full <- sapply(strsplit(rownames(germ_in_au),split="\\."),function(x) x[3]) 
germ_in_au$Context <- "German in Australia"
rownames(germ_in_au) <- NULL

# "English in Germany"
eng_in_germ <- do.call(rbind,lapply(sets[!(names(sets) %in% "comm.var")],function(x) {
  get_alpha(data=filtered_conv[filtered_conv$Context == "English in Germany",],
                      var=x)}))

# the ones that makes issues
get_alpha(data=filtered_conv[filtered_conv$Context == "English in Germany",],
                      var=sets$ought.var)

eng_in_germ$var <- sapply(strsplit(rownames(eng_in_germ),split="\\."),function(x) x[1]) 
eng_in_germ$var.full <- sapply(strsplit(rownames(eng_in_germ),split="\\."),function(x) x[3]) 
eng_in_germ$Context <- "English in Germany"
rownames(eng_in_germ) <- NULL

# "English in Italy"
eng_in_ita <- do.call(rbind,lapply(sets[!(names(sets) %in% "comm.var")],function(x) {
  get_alpha(data=filtered_conv[filtered_conv$Context == "English in Italy",],
                      var=x)}))
eng_in_ita$var <- sapply(strsplit(rownames(eng_in_ita),split="\\."),function(x) x[1]) 
eng_in_ita$var.full <- sapply(strsplit(rownames(eng_in_ita),split="\\."),function(x) x[3]) 
eng_in_ita$Context <- "English in Italy"
rownames(eng_in_ita) <- NULL


# combine
full_alpha <- rbind(eng_in_ita,eng_in_germ,germ_in_au,ita_in_au)
  • Plot alpha by variable

full_alpha %>% group_by(Context,var) %>% 
  summarise(st.alpha = unique(alpha.std.alpha),
            G6=unique(alpha.G6.smc.)) %>%
  ggplot(.,aes(x=var,y=st.alpha,colour=Context)) + geom_point() + geom_line(aes(group=Context)) + theme_bw()
all_melt <- all_melt %>% separate(variable,into=c("item","type"),sep="\\.",remove=FALSE)
p1=ggplot(all_melt,aes(x=variable,fill=value)) + geom_bar(position = "stack") + 
  facet_grid(Context~type,scales = "free") + ggtitle("Filtered dataset")+theme(axis.text.x = element_text(angle = 45, hjust = 1),axis.text=element_text(size=8))+theme_bw()

p2=ggplot(full_alpha,aes(x=var.full,y=drop.std.alpha,colour=Context)) + geom_point() + geom_line(aes(group=Context)) + theme_bw() + facet_wrap(~var,scales="free")

p4=ggplot(full_alpha,aes(x=var.full,y=drop.average_r,colour=Context)) + geom_point() + geom_line(aes(group=Context)) + theme_bw() + facet_wrap(~var,scales="free")

p3=full_alpha %>% group_by(Context,var) %>% 
  summarise(st.alpha = unique(alpha.std.alpha),
            G6=unique(alpha.G6.smc.)) %>%
  ggplot(.,aes(x=var,y=st.alpha,colour=Context)) + geom_point() + geom_line(aes(group=Context)) + theme(axis.text.x = element_text(angle = 45, hjust = 1),axis.text=element_text(size=8)) + theme_bw()


cowplot::plot_grid(p2,p3,nrow=2)
LS0tCnRpdGxlOiAiQW5hbHlzaXMgb2YgbWVyZ2VkIHF1ZXN0aW9ubmFpcmVzIgphdXRob3I6ICJBbm5hIFF1YWdsaWVyaSAmIFJpY2NhcmRvIEFtb3JhdGkiCmRhdGU6ICIwMy8wOS8yMDE3IgpvdXRwdXQ6CiAgZ2l0aHViX2RvY3VtZW50OgogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogNAogIGh0bWxfZG9jdW1lbnQ6CiAgICB0b2M6IHllcwogICAgdG9jX2RlcHRoOiAnNCcKICBodG1sX25vdGVib29rOgogICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICBmaWdfY2FwdGlvbjogeWVzCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcwogICAgdG9jOiB5ZXMKICAgIHRvY19mbG9hdDogeWVzCi0tLQoKIyBQbGFuIHRoYXQgSSB3cm90ZSB3aXRoIFJpY2hpJ3MgY29tbWVudHMKCkxpbmsgYXQgaHR0cHM6Ly9kb2NzLmdvb2dsZS5jb20vZG9jdW1lbnQvZC8xYmROZU9NQVlZOTBrOEZBYlBSV0dCZ1MxWUJFZFAwOWtQMHZjVzB0TmdQYy9lZGl0P3VzcD1zaGFyaW5nCgoKYGBge3IsbWVzc2FnZT1GQUxTRSwgZWNobz1GQUxTRX0KbGlicmFyeShyZWFkcikKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkocmVzaGFwZTIpCmxpYnJhcnkoY29ycnBsb3QpCmxpYnJhcnkocHN5Y2gpCmxpYnJhcnkocGhlYXRtYXApCmxpYnJhcnkoUkNvbG9yQnJld2VyKQpsaWJyYXJ5KGNvd3Bsb3QpCmxpYnJhcnkoZ3JpZEV4dHJhKQpsaWJyYXJ5KGNvd3Bsb3QpCmxpYnJhcnkocGhlYXRtYXApCmxpYnJhcnkoc2pQbG90KQpsaWJyYXJ5KHNqbGFiZWxsZWQpCmxpYnJhcnkoc2ptaXNjKQpsaWJyYXJ5KGtuaXRyKQpsaWJyYXJ5KHJlYWR4bCkKCmRhdGEoZWZjKQp0aGVtZV9zZXQodGhlbWVfc2pwbG90KCkpCgojIENodW5rIG9wdGlvbnMKa25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCBwcm9tcHQgPSBUUlVFLGNhY2hlID0gVFJVRSxmaWcud2lkdGggPSAxMixmaWcuaGVpZ2h0ID0gMTIpCgpgYGAKCiMgUmVhZCBpbiBkYXRhCgpgYGB7ciBtZXNzYWdlPUZBTFNFLG1lc3NhZ2U9RkFMU0V9CmV1cm9wZWFuIDwtIHJlYWRfY3N2KCIwMS1jbGVhbmluZ19kYXRhX2RhdGEvZXVyb3BlYW5fcmVjb2RlZC5jc3YiKQphdXN0cmFsaWFuIDwtIHJlYWRfY3N2KCIwMS1jbGVhbmluZ19kYXRhX2RhdGEvYXVzdHJhbGlhbl9yZWNvZGVkLmNzdiIpCgpkaW0oZXVyb3BlYW4pCmRpbShhdXN0cmFsaWFuKQoKZXVyb3BlYW4kRVUgPC0gMQphdXN0cmFsaWFuJEFVIDwtIDEKCmFsbCA8LSBtZXJnZShldXJvcGVhbixhdXN0cmFsaWFuLGFsbCA9IFRSVUUpCgp0YWJsZShhbGwkRVUsYWxsJEFVLHVzZU5BID0gImFsd2F5cyIpCmBgYAoKIyMgVmFyaWFibGVzIHRvIGRlc2NyaWJlIGRhdGFzZXQgKGNhbiBiZSBkaWZmZXJlbnQgYmV0d2VlbiBjb250ZXh0cykKCmBgYHtyfQpkZW1vZ3JhcGhpY3NfdmFyIDwtIGMoIkFnZSIsIkdlbmRlciIsIkwxIiwic3BlYWsub3RoZXIuTDIiLCJzdHVkeS5vdGhlci5MMiIsIm9yaWdpbnMiLCJ5ZWFyLnN0dWR5TDIiLCJvdGhlcjUub3RoZXIud2F5cyIsImRlZ3JlZSIsInJvbGVMMi5kZWdyZWUiLCJzdHVkeS55ZWFyIiwicHJvZiIsIkwyLlZDRSIsInVuaTEueWVhciIsIkNvbnRleHQiKQpsMlNjaG9vbCA8LSAiXFwuTDJzY2hvb2wkIgpsMlNjaG9vbF92YXJpYWJsZXMgPC0gY29sbmFtZXMoYWxsKVtncmVwKGwyU2Nob29sLGNvbG5hbWVzKGFsbCkpXQpgYGAKCi0gRmlyc3QgbGFuZ3VhZ2UKCmBgYHtyfQojdGFibGUoYWxsJEwxLGFsbCRDb250ZXh0KSAjIHRvbyBtYW55IGxldmVscyAtIG5lZWRzIHRvIGJlIGNsZWFuZWQgKGV4IHRvdCBudW1iZXIgb2YgbGFuZ3VhZ2VzPykKdGFibGUoYWxsJEwxLHVzZU5BID0gImFsd2F5cyIpCmdncGxvdChhbGwsYWVzKHg9TDEsZmlsbD1Db250ZXh0KSkgKyBnZW9tX2JhcigpICsgY29vcmRfZmxpcCgpICsgZ2d0aXRsZSgiRmlyc3QgTGFuZ3VhZ2UiKSArIGxhYnMoeT0iTi4gb2YgcGFydGljaXBhbnRzIix4PSIiKSt0aGVtZV9idygpCiN0YWJsZShhbGwkc3BlYWsub3RoZXIuTDIsYWxsJENvbnRleHQpCmBgYAoKYGBge3J9CkwyIDwtIGRhdGEuZnJhbWUoRnJlcT10YWJsZShhbGwkc3BlYWsub3RoZXIuTDIpW29yZGVyKHRhYmxlKGFsbCRzcGVhay5vdGhlci5MMiksZGVjcmVhc2luZyA9IFRSVUUpXSwKICAgICAgICAgICAgICAgICBMMj1uYW1lcyh0YWJsZShhbGwkc3BlYWsub3RoZXIuTDIpKVtvcmRlcih0YWJsZShhbGwkc3BlYWsub3RoZXIuTDIpLGRlY3JlYXNpbmcgPSBUUlVFKV0pICMgdG9vIG1hbnkgbGV2ZWxzIC0gbmVlZHMgdG8gYmUgY2xlYW5lZCAoZXggdG90IG51bWJlciBvZiBsYW5ndWFnZXM/KQpoZWFkKEwyKQpgYGAKCi0gb3JpZ2lucwoKYGBge3J9CnRhYmxlKGFsbCRvcmlnaW5zLHVzZU5BID0gImFsd2F5cyIpCmBgYAoKCmBgYHtyfQp0YWJsZShhbGwkeWVhci5zdHVkeUwyKQpgYGAKCmBgYHtyfQp0YWJsZShhbGwkZGVncmVlKQpgYGAKCi0gc3R1ZHkueWVhciBpbiB0aGUgRXVyb3BlYW4gY29udGV4dCBpcyB1bmkxLnllYXIgaW4gdGhlIEF1c3RyYWxpYW4gY29udGV4dAoKYGBge3J9CmFsbCRzdHVkeS55ZWFyW2lzLm5hKGFsbCRzdHVkeS55ZWFyKV0gPC0gYWxsJHVuaTEueWVhcltpcy5uYShhbGwkc3R1ZHkueWVhcildCiN0YWJsZShhbGwkc3R1ZHkueWVhcikKYWxsJHN0dWR5LnllYXIgPC0gaWZlbHNlKGFsbCRzdHVkeS55ZWFyID09ICJBbHJlYWR5IGdyYWR1YXRlZCBhZnRlciA1IHNlbWVzdGVycyBpbiBNYXJjaCAyMDE2LCB3YXMgaW50ZXJlc3RlZCBpbiBzdXJ2ZXJ5L3N0dWR5LCBzb3JyeS4iLCI2dGggc2VtZXN0ZXIiLGFsbCRzdHVkeS55ZWFyKQp0YWJsZShhbGwkc3R1ZHkueWVhcikKYGBgCgotIHByb2ZpY2llbmN5CgpgYGB7cn0KdGFibGUoYWxsJHByb2YsdXNlTkEgPSAiYWx3YXlzIikKYGBgCgojIEZpbHRlciBwYXJ0aWNpcGFudHMgOiBrZWVwIG9ubHkgdGhlIG9uZXMgdGhhdCBtZWV0IHRoZSBpbmNsdXNpb24gY3JpdGVyaWEKCmBgYHtyIEZpbHRlcmVkLGZpZy53aWR0aD0yMCxmaWcuaGVpZ2h0PTE1fQphbGwkc3R1ZHkueWVhcltpcy5uYShhbGwkc3R1ZHkueWVhcildIDwtIGFsbCR1bmkxLnllYXJbaXMubmEoYWxsJHN0dWR5LnllYXIpXQojIEZpbHRlciBvbmx5IHN1YmplY3QgdGhhdCB3ZSB3YW50IHRvIGluY2x1ZGUgaW4gdGhlIHN0dWR5CiMgbmFtZXModGFibGUoYWxsJHN0dWR5LnllYXIpKVsxXSA9IDFzdCBzZW1lc3RlciIKCmZpbHRlcmVkIDwtIHN1YnNldChhbGwsIChzdHVkeS55ZWFyID09ICIxc3QgeWVhciIpIHwgKHN0dWR5LnllYXIgPT0gbmFtZXModGFibGUoYWxsJHN0dWR5LnllYXIpKVsxXSkpCiMmIHllYXIuc3R1ZHlMMiAhPSAiMCB5ZWFycyIKCmBgYAoKCiMjIEltcHV0aW5nIGRlZ3JlZSBiYXNlZCBvbiBRdWFsaXR5IENvbW1lbnRzIHByb3ZpZGVkIGluIHRoZSBxdWVzdGlvbnMKCi0gKio1MzEzOTc2NzE2KiogOiBTQ0kgKHdpc2ggdG8gc3R1ZHkgc2NpZW5jZSBpbiB0aGUgZnV0dXJlKQotICoqNTM1OTg2NjU0NSoqIDogSFVNLlNDSSAoYmFzZWQgb24gZGVncmVlLm90aGVyNykKLSAqKjUzNzUzNzAxMjIqKiA6IFNDSSAoc2hlIHdhbnRzIHRvIGRvIHNjaWVuY2UpCi0gKio1Mzc1Mzc2NzYxKiogOiBIVU0gKHNoZSB3YW50cyB0byBkbyB0cmFuc2xhdGlvbi9yZXNlcmFjaC90ZWFjaGluZykKCmBgYHtyfQpmaWx0ZXJlZCRkZWdyZWVbZmlsdGVyZWQkUmVzcC5JRCAlaW4lICI1MzEzOTc2NzE2Il0gPC0gIlNDSSIKZmlsdGVyZWQkZGVncmVlW2ZpbHRlcmVkJFJlc3AuSUQgJWluJSAiNTM1OTg2NjU0NSJdIDwtICJIVU0uU0NJIgpmaWx0ZXJlZCRkZWdyZWVbZmlsdGVyZWQkUmVzcC5JRCAlaW4lICI1Mzc1MzcwMTIyIl0gPC0gIlNDSSIKZmlsdGVyZWQkZGVncmVlW2ZpbHRlcmVkJFJlc3AuSUQgJWluJSAiNTM3NTM3Njc2MSJdIDwtICJIVU0iCgp0YWJsZShmaWx0ZXJlZCRkZWdyZWUpCmthYmxlKHRhYmxlKGZpbHRlcmVkJENvbnRleHQpKQprYWJsZSh0YWJsZShmaWx0ZXJlZCR5ZWFyLnN0dWR5TDIsZmlsdGVyZWQkQ29udGV4dCkpCmthYmxlKHRhYmxlKGZpbHRlcmVkJHllYXIuc3R1ZHlMMixmaWx0ZXJlZCRwcm9mKSkKa2FibGUodGFibGUoZmlsdGVyZWQkeWVhci5zdHVkeUwyLGZpbHRlcmVkJENvbnRleHQpKQpgYGAKClBlb3BsZSB0aGF0IGhhdmUgc3R1ZGllZCAwIHllYXJzIEwyIGFyZSBqdXN0IGEgc21hbGwgc3Vic2V0IG9mIHRoZSBHZXJtYW4gaW4gQXVzdHJhbGlhIGFuZCBJdGFsaWFuIGluIEF1c3RyYWxpYSBjb250ZXh0IHdoaWNoIG1lYW5zIHRoYXQgYnkgY29ycmVjdGluZyBmb3IgY29udGV4dCB3ZSBhcmUgbm90IHJlbW92aW5nIHRoZSBlZmZlY3Qgb2YgdGhlIDAgeWVhcnMuIEEgd2F5IHRvIHJlbW92ZSB0aGUgZWZmZWN0IG9mIHRoZSAwIHllYXJzIHBhcnRpY2lwYW50cyBhbmQgbm90IGluY2x1ZGluZyB0b28gbWFueSB2YXJpYWJsZXMgY291bGQgYmUgdG8gZXN0aW1hdGUgdGhlIGVmZmVjdCBvZiAwIHllYXJzIHZzIGFsbC4gCgojIERlZmluZSBkZW1vZ3JhcGhpYyB2YXJpYWJsZXMKCiMjIE5lZWQgdG8gY2hlY2sgZGF0YXNldHMgd2l0aCBSY2loaSAod2h5IGRvIHdlIGhhdmUgUUMgaW4gTDE/IEFtIEkgdXNpbmcgbm90IHRoZSBsYXRlc3QgZGF0YXNldD8pCgpgYGB7ciBtZXNzYWdlPUZBTFNFfQphbGwgPC0gZmlsdGVyZWQKZGVtb2dyYXBoaWNzX3ZhciA8LSBjKCJBZ2UiLCJHZW5kZXIiLCJMMSIsInNwZWFrLm90aGVyLkwyIiwic3R1ZHkub3RoZXIuTDIiLCJvcmlnaW5zIiwieWVhci5zdHVkeUwyIiwib3RoZXI1Lm90aGVyLndheXMiLCJkZWdyZWUiLCJyb2xlTDIuZGVncmVlIiwic3R1ZHkueWVhciIsInByb2YiLCJMMi5WQ0UiLCJ1bmkxLnllYXIiLCJDb250ZXh0IikKbDJTY2hvb2wgPC0gIlxcLkwyc2Nob29sJCIKbDJTY2hvb2xfdmFyaWFibGVzIDwtIGNvbG5hbWVzKGFsbClbZ3JlcChsMlNjaG9vbCxjb2xuYW1lcyhhbGwpKV0KCmdncGxvdChhbGwsYWVzKHg9TDEsZmlsbD1Db250ZXh0KSkgKyBnZW9tX2JhcigpICsgY29vcmRfZmxpcCgpICsgZ2d0aXRsZSgiRmlyc3QgTGFuZ3VhZ2UiKSArIGxhYnMoeT0iTi4gb2YgcGFydGljaXBhbnRzIix4PSIiKSArIHRoZW1lX2J3KCkKCnRhYmxlKGFsbCRMMSxhbGwkQ29udGV4dCkKCnRhYmxlKGFsbCRkZWdyZWUsYWxsJEwxKQpgYGAKCi0gQ2hlY2sgZm9yIEwxIGJ1dCB3ZSBkZWNpZGVkIG5vdCB0byBmaWx0ZXIgZm9yIGl0CgpgYGB7cn0KI0ZpbHRlciBieSBMMQoKbmMgPC0gbmFtZXModGFibGUoYWxsJENvbnRleHQpKQp0YWJsZShhbGwkQ29udGV4dCkKbDFfZmlsdGVyIDwtIGFsbFsoYWxsJENvbnRleHQgPT0gbmNbMV0gJiAoYWxsJEwxID09ICJHZXJtYW4iIHwgYWxsJEwxID09ICJHZXJtYW4gYW5kIEVuZ2xpc2giKSkgfCAKICAgICAgICAgICAgICAgICAgICAoYWxsJENvbnRleHQgPT0gbmNbMl0gJiAoYWxsJEwxID09ICJJdGFsaWFuIikpIHwgCiAgICAgICAgICAgICAgICAgICAgKGFsbCRDb250ZXh0ID09IG5jWzNdICYgKGFsbCRMMSA9PSAiRW5nbGlzaCIgfCBhbGwkTDEgPT0gIkVuZ2xpc2ggYW5kIER1dGNoIiB8IGFsbCRMMSA9PSAiR2VybWFuIGFuZCBFbmdsaXNoIikpIHwKICAgICAgICAgICAgICAgICAgICAoYWxsJENvbnRleHQgPT0gbmNbNF0gJiAoYWxsJEwxID09ICJFbmdsaXNoIiB8IGFsbCRMMSA9PSAiRW5nbGlzaCBhbmQgRHV0Y2giIHwgYWxsJEwxID09ICJHZXJtYW4gYW5kIEVuZ2xpc2giKSksXQoKCiNhbGwgPC0gbDFfZmlsdGVyCgojIGRvIG5vdCBmaWx0ZXIgZm9yIEwxCmFsbCA8LSBhbGwKCiMgc3Vic2V0IGRlbW9ncmFwaGljcwpkZW1vIDwtIHN1YnNldChhbGwsc2VsZWN0PWMoIlJlc3AuSUQiLGRlbW9ncmFwaGljc192YXIsbDJTY2hvb2xfdmFyaWFibGVzKSkKCiMgTnVtZXJpIGZpbmFsaQp0YWJsZShsMV9maWx0ZXIkQ29udGV4dCkKdGFibGUoYWxsJENvbnRleHQpCgpgYGAKCi0gRmlsdGVyIG1pc3NpbmcgdmFsdWU6CiAgLSBGaWx0ZXIgcGFydGljaXBhbnRzIHdobyBkaWRuJ3QgcHV0IHRoZSBkZWdyZWUKICAtIHdlIGRvbid0IGNhcmUgYWJvdXQgc3BlYWsub3RoZXIuTDIgYW5kIHN0dWR5Lm90aGVyLkwyCgpgYGB7cn0KbWlzc2luZ19ieVNhbXBsZSA8LSByb3dTdW1zKGlzLm5hKGRlbW8pKQpuYW1lcyhtaXNzaW5nX2J5U2FtcGxlKSA8LSBkZW1vJFJlc3AuSUQKbWlzc2luZ19ieVZhciA8LSBjb2xTdW1zKGlzLm5hKGRlbW8pKQpuYW1lcyhtaXNzaW5nX2J5VmFyKSA8LSBjb2xuYW1lcyhkZW1vKQoKYmFycGxvdChtaXNzaW5nX2J5U2FtcGxlKQpkIDwtIGRhdGEuZnJhbWUobWlzcz1taXNzaW5nX2J5VmFyKQpkJHZhcklEIDwtIHJvd25hbWVzKGQpCmdncGxvdChkYXRhPWQsYWVzKHg9dmFySUQseT1taXNzKSkgKyBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpICsgdGhlbWVfYncoKSArdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkgCgoKZGVtb19taXNzaW5nIDwtIGRlbW8gJT4lIGdyb3VwX2J5KENvbnRleHQpICU+JSBzdW1tYXJpc2Uocm9sZUwyLmRlZ3JlZV9uYSA9IHN1bShpcy5uYShyb2xlTDIuZGVncmVlKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEwyLlZDRV9uYSA9IHN1bShpcy5uYShMMi5WQ0UpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3RoZXI1Lm90aGVyLndheXNfbmE9c3VtKGlzLm5hKG90aGVyNS5vdGhlci53YXlzICkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmkxLnllYXJfbmEgPSBzdW0oaXMubmEodW5pMS55ZWFyKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW1hcnkxLkwyc2Nob29sX25hPXN1bShpcy5uYShwcmltYXJ5MS5MMnNjaG9vbCkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDTFMzLkwyc2Nob29sX25hID0gc3VtKGlzLm5hKENMUzMuTDJzY2hvb2wpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVlNMNC5MMnNjaG9vbF9uYT1zdW0oaXMubmEoVlNMNC5MMnNjaG9vbCkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWdyZWUgPSBzdW0oaXMubmEoZGVncmVlKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjaG9vTDJjb3VudHJ5NS5MMnNjaG9vbF9uYT1zdW0oaXMubmEoc2Nob29MMmNvdW50cnk1Lkwyc2Nob29sKSkpCgojIFdlIGRvIG5vdCBmaWx0ZXIgZm9yIHNwZWFrLm90aGVyLkwyIG9yIHN0dWR5Lm90aGVyLkwyCgojZGVtb1tpcy5uYShkZW1vJHNwZWFrLm90aGVyLkwyKSxdCiMgdGVuaWFtbwojZGVtb1tpcy5uYShkZW1vJHN0dWR5Lm90aGVyLkwyKSxdCm1pc3NpbmdfYnlTYW1wbGVbbmFtZXMobWlzc2luZ19ieVNhbXBsZSkgPT0gIjUxNjY4NjE1ODEiXQojZGVtb1tpcy5uYShkZW1vJHllYXIuc3R1ZHlMMiksXQptaXNzaW5nX2J5U2FtcGxlW25hbWVzKG1pc3NpbmdfYnlTYW1wbGUpID09ICI1Mzc4Nzk4Nzg3Il0KCiMgcmVtb3ZlIE5BIGZyb20gZGVncmVlCiN0YWJsZShkZW1vJGRlZ3JlZSx1c2VOQSA9ICJhbHdheXMiKQojIFJlbW92ZSBwZW9wbGUKYWxsIDwtIGFsbFshaXMubmEoYWxsJGRlZ3JlZSksXQpgYGAKCiMjIFN0YXRzIGFib3V0IGZpbHRlcmVkIGRhdGFzZXQKCmBgYHtyfQprYWJsZSh0YWJsZShhbGwkQ29udGV4dCkpCmthYmxlKHRhYmxlKGFsbCRzdHVkeS55ZWFyKSkKa2FibGUodGFibGUoYWxsJHllYXIuc3R1ZHlMMikpCmBgYAoKIyMgUmVjb2RlZCBkZW1vZ3JhcGhpYyB2YXJpYWJsZXMKCmBgYHtyfQpyZWNvZGVkX2RlbV9yaWNoaSA8LSByZWFkX2V4Y2VsKCIwMi1kZXNjcmlwdGl2ZV9kYXRhLzIxIDAzIG1lcmdlZF9maWx0ZXJlZF9pbXB1dGVkTWVkaWFuX2xpa2VydE51bWJlci54bHN4IikKYGBgCgoKIyMgV3JpdGUgZmlsdGVyZWQgYW5kIG1lcmdlZCBkYXRhc2V0CgpgYGB7cn0Kd3JpdGUuY3N2KGFsbCxmaWxlLnBhdGgoIjAyLWRlc2NyaXB0aXZlX2RhdGEvY29udGV4dC1tZXJnZWRfZmlsdGVyZWQuY3N2IikpCmBgYAoKIyMgRGVzY3JpcHRpdmUgcGxvdHMgYW5kIHRhYmxlcwoKYGBge3Igc3BlYWsub3RoZXIuTDJfYmluYXJ5LG1lc3NhZ2U9RkFMU0V9CmFsbCRzcGVhay5vdGhlci5MMl9iaW5hcnkgPC0gaWZlbHNlKCFpcy5uYShhbGwkc3BlYWsub3RoZXIuTDIpICYgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIShhbGwkc3BlYWsub3RoZXIuTDIgJWluJSBjKCJZZXMiLCJObyIpKSwiWWVzIixhcy5jaGFyYWN0ZXIoYWxsJHNwZWFrLm90aGVyLkwyKSkKCgprYWJsZSh0YWJsZShhbGwkc3BlYWsub3RoZXIuTDJfYmluYXJ5LGFsbCRDb250ZXh0LHVzZU5BID0gImFsd2F5cyIpKQoKYGBgCgotIEFnZQoKYGBge3IgYWdlX2J5X2NvbnRleHQsbWVzc2FnZT1GQUxTRX0KdGFiQWdlIDwtIHQodGFibGUoYWxsJEFnZSxhbGwkQ29udGV4dCkpCmdnZGYgPC0gZGF0YS5mcmFtZShBZ2UgPSByZXAoY29sbmFtZXModGFiQWdlKSxlYWNoPTQpWyEoYXMubnVtZXJpYyh0YWJBZ2UpID09IDApXSwKICBOLlBhcnRpY2lwYW50cyA9IGFzLm51bWVyaWModGFiQWdlKVshKGFzLm51bWVyaWModGFiQWdlKSA9PSAwKV0sCiAgQ29udGV4dCA9IHJlcChyb3duYW1lcyh0YWJBZ2UpLHRpbWVzPTMpWyEoYXMubnVtZXJpYyh0YWJBZ2UpID09IDApXSkKCmdncGxvdChnZ2RmLGFlcyh4PUFnZSx5PU4uUGFydGljaXBhbnRzLGZpbGw9Q29udGV4dCkpICsgZ2VvbV9iYXIocG9zaXRpb249ImRvZGdlIixjb2xvdXI9IndoaXRlIixzdGF0PSJpZGVudGl0eSIpICArIHNjYWxlX3lfY29udGludW91cyhicmVha3M9c2VxKDAsOTAsMTApLGxpbWl0cz1jKDAsOTApKSArIHRoZW1lX2J3KCkgKyBnZ3RpdGxlKCJQYXJ0aWNpcGFudHMgYnkgYWdlIikrCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IE4uUGFydGljaXBhbnRzKSwgaGp1c3Q9MC41LCB2anVzdD0tMC4yNSwgc2l6ZSA9IDIuNSxwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjkpKSAKCmBgYAoKYGBge3IgZ2VuZGVyX2J5X2NvbnRleHQsbWVzc2FnZT1GQUxTRX0KIyBhZGQgbnVtYmVycyBvbiB0aGUgYmFyCgp0YWJBZ2UgPC0gdCh0YWJsZShhbGwkR2VuZGVyLGFsbCRDb250ZXh0KSkKZ2dkZiA8LSBkYXRhLmZyYW1lKEdlbmRlciA9IHJlcChjb2xuYW1lcyh0YWJBZ2UpLGVhY2g9NClbIShhcy5udW1lcmljKHRhYkFnZSkgPT0gMCldLAogIE4uUGFydGljaXBhbnRzID0gYXMubnVtZXJpYyh0YWJBZ2UpWyEoYXMubnVtZXJpYyh0YWJBZ2UpID09IDApXSwKICBDb250ZXh0ID0gcmVwKHJvd25hbWVzKHRhYkFnZSksdGltZXM9MylbIShhcy5udW1lcmljKHRhYkFnZSkgPT0gMCldKQoKCmdncGxvdChnZ2RmLGFlcyh4PUdlbmRlcix5PU4uUGFydGljaXBhbnRzLGZpbGw9Q29udGV4dCkpICsgZ2VvbV9iYXIocG9zaXRpb249ImRvZGdlIixjb2xvdXI9IndoaXRlIixzdGF0PSJpZGVudGl0eSIpICArIGxhYnMoeT0iTiBwYXJ0aWNpcGFudHMiKSArIHNjYWxlX3lfY29udGludW91cyhicmVha3M9c2VxKDAsOTAsMTApLGxpbWl0cz1jKDAsOTApKSArIHRoZW1lX2J3KCkgKyBnZ3RpdGxlKCJQYXJ0aWNpcGFudHMgYnkgZ2VuZGVyIikrICBnZW9tX3RleHQoYWVzKGxhYmVsID0gTi5QYXJ0aWNpcGFudHMpLCBoanVzdD0wLjUsIHZqdXN0PS0wLjI1LCBzaXplID0gMi41LHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuOSkpIAoKYGBgCgpgYGB7ciBvcmlnbnNfYnlfY29udGV4dCxtZXNzYWdlPUZBTFNFfQojIGFkZCBudW1iZXJzIG9uIHRoZSBiYXIKdGFiQWdlIDwtIHQodGFibGUoYWxsJG9yaWdpbnMsYWxsJENvbnRleHQpKQpnZ3Bsb3QoYWxsLGFlcyh4PW9yaWdpbnMsZmlsbD1Db250ZXh0KSkgKyBnZW9tX2Jhcihwb3NpdGlvbj0iZG9kZ2UiLGNvbG91cj0id2hpdGUiKSArIGdndGl0bGUoIk9yaWdpbnMgYnkgY29udGV4dCIpICsgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcz1zZXEoMCw5MCwxMCksbGltaXRzPWMoMCw5MCkpICsgdGhlbWVfYncoKSArIGRyYXdfZ3JvYih0YWJsZUdyb2IodGFiQWdlKSwgeD0yLCB5PTYwLCB3aWR0aD0wLjMsIGhlaWdodD0wLjQpICsgZ2d0aXRsZSgiUGFydGljaXBhbnRzIGJ5IG9yaWdpbnMiKQp0YWJBZ2UKYGBgCgotIHByb2ZpY2llbmN5CgpgYGB7ciBwcm9maWNpZW5jeV9ieV9jb250ZXh0LG1lc3NhZ2U9RkFMU0V9CnRhYkFnZSA8LSB0KHRhYmxlKGFsbCRwcm9mLGFsbCRDb250ZXh0KSkKZ2dwbG90KGFsbCxhZXMoeD1Db250ZXh0LGZpbGw9cHJvZikpICsgZ2VvbV9iYXIocG9zaXRpb249ImRvZGdlIixjb2xvdXI9IndoaXRlIikgKyBnZ3RpdGxlKCJQcm9maWNpZW5jeSBieSBjb250ZXh0IikgKyBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgwLDkwLDEwKSxsaW1pdHM9YygwLDkwKSkgKyB0aGVtZV9idygpICsgZHJhd19ncm9iKHRhYmxlR3JvYih0YWJBZ2UpLCB4PTIsIHk9ODAsIHdpZHRoPTAuMywgaGVpZ2h0PTAuNCkKdGFiQWdlCmBgYAoKLSBMMi5WQ0UKCmBgYHtyIEwyVkNFX2J5X2NvbnRleHQsbWVzc2FnZT1GQUxTRX0KdGFiQWdlIDwtIHQodGFibGUoYWxsW2FsbCRDb250ZXh0ICE9ICJFbmdsaXNoIGluIEdlcm1hbnkiICYgYWxsJENvbnRleHQgIT0gIkVuZ2xpc2ggaW4gSXRhbHkiLCJMMi5WQ0UiXSxhbGxbYWxsJENvbnRleHQgIT0gIkVuZ2xpc2ggaW4gR2VybWFueSIgJiBhbGwkQ29udGV4dCAhPSAiRW5nbGlzaCBpbiBJdGFseSIsJ0NvbnRleHQnXSx1c2VOQSA9ICJhbHdheXMiKSkKdGFiQWdlIDwtIHRhYkFnZVstMyxdCgpnZ3Bsb3QoYWxsW2FsbCRDb250ZXh0ICE9ICJFbmdsaXNoIGluIEdlcm1hbnkiICYgYWxsJENvbnRleHQgIT0gIkVuZ2xpc2ggaW4gSXRhbHkiLF0sYWVzKHg9Q29udGV4dCxmaWxsPUwyLlZDRSkpICsgZ2VvbV9iYXIocG9zaXRpb249ImRvZGdlIixjb2xvdXI9IndoaXRlIikgKyBnZ3RpdGxlKCJMMi5WQ0UgYnkgY29udGV4dCIpICsgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcz1zZXEoMCw5MCwxMCksbGltaXRzPWMoMCw5MCkpICsgdGhlbWVfYncoKSArIGRyYXdfZ3JvYih0YWJsZUdyb2IodGFiQWdlKSwgeD0yLCB5PTgwLCB3aWR0aD0wLjMsIGhlaWdodD0wLjQpCmBgYAoKLSBkYSBtZXR0ZXJlIGEgcG9zdG8gY29uIFJpY2hpCgpgYGB7ciB5ZWFyLnN0dWR5TDJfRXVyb3BlYW5fY29udGV4dCxtZXNzYWdlPUZBTFNFfQojIHllYXIgc3R1ZHkgTDIKdGFibGUoYWxsJHllYXIuc3R1ZHlMMixhbGwkb3RoZXIueWVhci5zdHVkeUwyLnJpY2hpKQoKYWxsJHllYXIuc3R1ZHlMMiA8LSBpZmVsc2UoYWxsJHllYXIuc3R1ZHlMMiA9PSAiT3RoZXIiLGFsbCRvdGhlci55ZWFyLnN0dWR5TDIucmljaGksYWxsJHllYXIuc3R1ZHlMMiApCgojIEV1cm9wZWFuIGNvbnRleHQKZ2dwbG90KGFsbFthbGwkQ29udGV4dCA9PSAiRW5nbGlzaCBpbiBHZXJtYW55IiB8IGFsbCRDb250ZXh0ID09ICJFbmdsaXNoIGluIEl0YWx5IixdLGFlcyh4PWRlZ3JlZSxmaWxsPXllYXIuc3R1ZHlMMikpICsgZ2VvbV9iYXIocG9zaXRpb249ImRvZGdlIixjb2xvdXI9IndoaXRlIikgKyB0aGVtZV9idygpICsgZ2d0aXRsZSgiRGVncmVlIGJ5IHN0dWR5IHllYXIgTDIsIGJ5IENvbnRleHQiKSArICBmYWNldF9ncmlkKH5Db250ZXh0LHNjYWxlcz0iZnJlZSIpICsgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkgKyBsYWJzKHkgPSAiTiBwYXJ0aWNpcGFudHMiLCB4ID0gImRlZ3JlZSIpCmBgYAoKLSBEZWdyZWUgb2YgZW5yb2xtZW50CgpgYGB7ciBkZWdyZWVfYnlfY29udGV4dCxtZXNzYWdlPUZBTFNFfQojIEF1c3RyYWxpYW4gY29udGV4dAp0YWJBZ2UgPC0gdCh0YWJsZShhbGxbYWxsJENvbnRleHQgPT0gIkl0YWxpYW4gaW4gQXVzdHJhbGlhIiB8IGFsbCRDb250ZXh0ID09ICJHZXJtYW4gaW4gQXVzdHJhbGlhIiwnZGVncmVlJ10sYWxsW2FsbCRDb250ZXh0ID09ICJJdGFsaWFuIGluIEF1c3RyYWxpYSIgfCBhbGwkQ29udGV4dCA9PSAiR2VybWFuIGluIEF1c3RyYWxpYSIsJ0NvbnRleHQnXSkpCmdncGxvdChhbGxbYWxsJENvbnRleHQgPT0gIkl0YWxpYW4gaW4gQXVzdHJhbGlhIiB8IGFsbCRDb250ZXh0ID09ICJHZXJtYW4gaW4gQXVzdHJhbGlhIixdLGFlcyh4PUNvbnRleHQsZmlsbD1kZWdyZWUpKSArIGdlb21fYmFyKHBvc2l0aW9uPSJkb2RnZSIsY29sb3VyPSJ3aGl0ZSIpICsgdGhlbWVfYncoKSArIGdndGl0bGUoIkRlZ3JlZSBpbiBBdXN0cmFsaWFuIENvbnRleHRzIikgKyBkcmF3X2dyb2IodGFibGVHcm9iKHRhYkFnZSksIHg9MS4sIHk9NDAsIHdpZHRoPTAuMywgaGVpZ2h0PTAuNCkKdGFiQWdlCmBgYAoKYGBge3IgeWVhci5zdHVkeUwyX0F1c3RyYWxpYW5fY29udGV4dCxtZXNzYWdlPUZBTFNFfQojIEF1c3RyYWxpYW4gY29udGV4dAp0YWJBZ2UgPC0gdCh0YWJsZShhbGxbYWxsJENvbnRleHQgPT0gIkVuZ2xpc2ggaW4gSXRhbHkiIHwgYWxsJENvbnRleHQgPT0gIkVuZ2xpc2ggaW4gR2VybWFueSIsJ2RlZ3JlZSddLGFsbFthbGwkQ29udGV4dCA9PSAiRW5nbGlzaCBpbiBJdGFseSIgfCBhbGwkQ29udGV4dCA9PSAiRW5nbGlzaCBpbiBHZXJtYW55IiwnQ29udGV4dCddKSkKCmdncGxvdChhbGxbYWxsJENvbnRleHQgPT0gIkVuZ2xpc2ggaW4gSXRhbHkiIHwgYWxsJENvbnRleHQgPT0gIkVuZ2xpc2ggaW4gR2VybWFueSIsXSxhZXMoeD1Db250ZXh0LGZpbGw9ZGVncmVlKSkgKyBnZW9tX2Jhcihwb3NpdGlvbj0iZG9kZ2UiLGNvbG91cj0id2hpdGUiKSArIHRoZW1lX2J3KCkgKyBnZ3RpdGxlKCJEZWdyZWUgaW4gRXVyb3BlYW4gQ29udGV4dHMiKQoKdGFiQWdlCmBgYAoKCiMgQXVzdHJhbGlhbiBjb250ZXh0IHNwY2lmaWMgdmFyaWFibGVzIAoKYGBge3J9CmthYmxlKHRhYmxlKGFsbCRyZWNvbm5lY3QuY29tbSxhbGwkQ29udGV4dCkpCmthYmxlKHRhYmxlKGFsbCRzcGVha2Vyc21lbGIuY29tbSxhbGwkQ29udGV4dCkpCmthYmxlKHRhYmxlKGFsbCRjb21lY2xvc2VyLmNvbW0sYWxsJENvbnRleHQpKQpgYGAKCgpcY2xlYXJwYWdlCgojIExpa2VydCBzY2FsZXMKCmBgYHtyIGluY2x1ZGU9RkFMU0UsbWVzc2FnZT1GQUxTRX0KbGlrZXJ0X2dyZXAgPC0gIlxcLmlkJHxcXC5vdWdodCR8XFwuaW50ciR8XFwuaW5zdHJ1JHxcXC5pbnRlZ3IkfFxcLnByb2YkfFxcLnBvc3QkfFxcLmNvbW0kfF5uZWNlc3NpdHkkfF5lZHVjYXRlZCQiCgojIGFsbApsaWtlcnRfdmFyaWFibGVzX2FsbCA8LSBjb2xuYW1lcyhhbGwpW2dyZXAobGlrZXJ0X2dyZXAsY29sbmFtZXMoYWxsKSldCmxpa2VydF92YXJpYWJsZXNfYWxsCmxpa2VydF92YXJpYWJsZXNfYWxsIDwtIGxpa2VydF92YXJpYWJsZXNfYWxsWyEobGlrZXJ0X3ZhcmlhYmxlc19hbGwgJWluJSAib3RoZXIucHJvZiIpXQoKYGBgCgotICoqQ29udmVydCBMaWtlcnQgc2NhbGVzIHRvIG51bWJlcnMqKgoKYGBge3IgZmlnLndpZHRoPTE1LGZpZy5oZWlnaHQ9MTV9Cgpjb252ZXJ0VG9OdW1iZXIgPC0gZnVuY3Rpb24oY29sdW1uKXsKICBjb2x1bW4gPC0gZmFjdG9yKGNvbHVtbixsZXZlbHMgPSBjKCJTdHJvbmdseSBkaXNhZ3JlZSIsIkRpc2FncmVlIiwiTm90IHN1cmUiLCJBZ3JlZSIsIlN0cm9uZ2x5IGFncmVlIikpCiAgY29sdW1uX251bWJlciA8LSBhcy5udW1lcmljKGNvbHVtbikKICByZXR1cm4oY29sdW1uX251bWJlcikKfQoKdGFibGUoYWxsJENvbnRleHQpCnRhYmxlKGFsbCRzdHVkeS55ZWFyKQoKY29udmVydF9saWtlcnQgPC0gZGF0YS5mcmFtZShhcHBseShzdWJzZXQoYWxsLHNlbGVjdD1saWtlcnRfdmFyaWFibGVzX2FsbCksMixjb252ZXJ0VG9OdW1iZXIpKQpjb2xuYW1lcyhjb252ZXJ0X2xpa2VydCkgPC0gcGFzdGUwKGNvbG5hbWVzKGNvbnZlcnRfbGlrZXJ0KSwiMSIpCgpsaWtlcnRfdmFyaWFibGVzMSA8LSBwYXN0ZTAobGlrZXJ0X3ZhcmlhYmxlc19hbGwsIjEiKQoKIyBqb2luIHRoZSBjb252ZXJ0ZWQgdmFyaWFibGVzIHRvIHRoZSBmaWx0ZXJlZCBkYXRhc2V0CmZpbHRlcmVkX2NvbnYgPC0gY2JpbmQoYWxsLGNvbnZlcnRfbGlrZXJ0KQoKdGFibGUoZmlsdGVyZWRfY29udlssbGlrZXJ0X3ZhcmlhYmxlc19hbGxbNF1dLGZpbHRlcmVkX2NvbnZbLGxpa2VydF92YXJpYWJsZXMxWzRdXSx1c2VOQSA9ICJhbHdheXMiKQoKd3JpdGUuY3N2KGZpbHRlcmVkX2NvbnYsIjAyLWRlc2NyaXB0aXZlX2RhdGEvbWVyZ2VkX2ZpbHRlcmVkX2xpa2VydE51bWJlci5jc3YiLHJvdy5uYW1lcyA9IEZBTFNFKQpgYGAKCiMjIEltcHV0ZSBtaXNzaW5nIHZhbHVlcyAtIFVzaW5nIG1lZGlhbiB2YWx1ZXMKClRoZSBtaXNzaW5nIHZhbHVlcyBhcHBlYXJzIHRvIGJlIGF0IHJhbmRvbSBhbmQgdGhlcmUgYXJlIG1heCB0d28gbWlzc2luZyB2YWx1ZXMgaW4gb25lIHZhcmlhYmxlIChzZWUgcGxvdHMgYmVsb3cpLiBJbiBvcmRlciBub3QgdG8gbG9vc2UgMTIgcGFydGljaXBhbnRzIHdoaWxlIGRvaW5nIHRoZSBmYWN0b3IgYW5hbHlzaXMgYWNyb3NzIGNvbnRleHRzIGl0IGlzIHByZWZlcmFibGUgdG8gaW1wdXRlIHRoZSAxMiBtaXNzaW5nIHZhbHVlcy4gCgpgYGB7cn0KYWxsIDwtIGZpbHRlcmVkX2NvbnYKCiMgSXRlbXMgdG8gdXNlIGZvciBmYWN0b3IgYW5hbHlzaXMgOiBpdGVtcyBzaGFyZWQgYmV0d2VlbiBjb250ZXh0cwojIGl0ZW1zIHRvIGJlIHVzZWQgZm9yIHRoZSBGQQoKdXNhYmxlX2l0ZW1zIDwtIGxpa2VydF92YXJpYWJsZXMxWyEobGlrZXJ0X3ZhcmlhYmxlczEgJWluJSBjKCJuZWNlc3NpdHkxIiwiZWR1Y2F0ZWQxIiwicmVjb25uZWN0LmNvbW0xIiwgInNwZWFrZXJzbWVsYi5jb21tMSIsICJjb21lY2xvc2VyLmNvbW0xIikpXQpgYGAKCgpgYGB7cn0Kcm93bmFtZXMoYWxsKSA8LSBhbGwkUmVzcC5JRAp1c2FibGVfZGF0YV9jb250ZXh0IDwtIGFsbFssYyh1c2FibGVfaXRlbXMsIkNvbnRleHQiKV0KZGF0X25vTkEgPC0gdXNhYmxlX2RhdGFfY29udGV4dFtyb3dTdW1zKGlzLm5hKHVzYWJsZV9kYXRhX2NvbnRleHQpKSA9PSAwLF0KYWxsX25vTkEgPC0gYWxsW3Jvd1N1bXMoaXMubmEodXNhYmxlX2RhdGFfY29udGV4dCkpID09IDAsXQp0YWJsZShyb3dTdW1zKGlzLm5hKHVzYWJsZV9kYXRhX2NvbnRleHQpKSkKIyBQYXJ0aWNpcGFudHMgd2l0aCBOQSB0byByZW1vdmUKdGFibGUocm93U3Vtcyhpcy5uYSh1c2FibGVfZGF0YV9jb250ZXh0KSksdXNhYmxlX2RhdGFfY29udGV4dCRDb250ZXh0LHVzZU5BID0gImFsd2F5cyIpCgojIFZhcmlhYmxlIG1pc3NpbmcgdmFsdWVzCnRhYmxlKGNvbFN1bXMoaXMubmEodXNhYmxlX2RhdGFfY29udGV4dCkpKQp0YWJsZShyb3dTdW1zKGlzLm5hKHVzYWJsZV9kYXRhX2NvbnRleHQpKSx1c2FibGVfZGF0YV9jb250ZXh0JENvbnRleHQsdXNlTkEgPSAiYWx3YXlzIikKCiMgY2hlY2sgd2hhdCB0byB1c2UgdG8gaW1wdXRlCiMgaGF2ZSBhIGxvb2sgYXQgdGhlIGRpc3RyaWJ1dGlvbiBvZiBtaXNzaW5nIHZhbHVlcwpsaWJyYXJ5KG1pY2UpCmxpYnJhcnkoVklNKQoKbWljZV9wbG90IDwtIGFnZ3IodXNhYmxlX2RhdGFfY29udGV4dFssdXNhYmxlX2l0ZW1zXSwgY29sPWMoJ25hdnlibHVlJywneWVsbG93JyksCiAgICAgICAgICAgICAgICAgICAgbnVtYmVycz1UUlVFLCBzb3J0VmFycz1UUlVFLAogICAgICAgICAgICAgICAgICAgIGxhYmVscz1uYW1lcyh1c2FibGVfZGF0YV9jb250ZXh0Wyx1c2FibGVfaXRlbXNdKSwgY2V4LmF4aXM9LjQsCiAgICAgICAgICAgICAgICAgICAgZ2FwPTEsIHlsYWI9YygiTWlzc2luZyBkYXRhIiwiUGF0dGVybiIpLGNleC5udW1iZXJzPTAuNSkKCiMgSW1wdXRpbmcgdXNpbmcgbWVkaWFuCmxpYnJhcnkoSG1pc2MpCmltcHV0ZWRNZWRpYW4gPC0gdXNhYmxlX2RhdGFfY29udGV4dAoKaW1wdXRlZE1lZGlhbiRnbG9iYWxhY2Nlc3MucG9zdDEgPC0gd2l0aChpbXB1dGVkTWVkaWFuWyx1c2FibGVfaXRlbXNdLCBpbXB1dGUoZ2xvYmFsYWNjZXNzLnBvc3QxLCBtZWRpYW4pKQppbXB1dGVkTWVkaWFuJGNpdGl6ZW4ucG9zdDEgPC0gd2l0aChpbXB1dGVkTWVkaWFuWyx1c2FibGVfaXRlbXNdLCBpbXB1dGUoY2l0aXplbi5wb3N0MSwgbWVkaWFuKSkKaW1wdXRlZE1lZGlhbiRtb25leS5pbnN0cnUxIDwtIHdpdGgoaW1wdXRlZE1lZGlhblssdXNhYmxlX2l0ZW1zXSwgaW1wdXRlKG1vbmV5Lmluc3RydTEsIG1lZGlhbikpCmltcHV0ZWRNZWRpYW4ka25vd2xlZGdlLmluc3RydTEgPC0gd2l0aChpbXB1dGVkTWVkaWFuWyx1c2FibGVfaXRlbXNdLCBpbXB1dGUoa25vd2xlZGdlLmluc3RydTEsIG1lZGlhbikpCmltcHV0ZWRNZWRpYW4kbGlmZS5pbnRyMSA8LSB3aXRoKGltcHV0ZWRNZWRpYW5bLHVzYWJsZV9pdGVtc10sIGltcHV0ZShsaWZlLmludHIxLCBtZWRpYW4pKQppbXB1dGVkTWVkaWFuJHRpbWUuaW50ZWdyMSA8LSB3aXRoKGltcHV0ZWRNZWRpYW5bLHVzYWJsZV9pdGVtc10sIGltcHV0ZSh0aW1lLmludGVncjEsIG1lZGlhbikpCmltcHV0ZWRNZWRpYW4kZXhwZWN0Lm91Z2h0MSA8LSB3aXRoKGltcHV0ZWRNZWRpYW5bLHVzYWJsZV9pdGVtc10sIGltcHV0ZShleHBlY3Qub3VnaHQxLCBtZWRpYW4pKQppbXB1dGVkTWVkaWFuJGpvYi5pbnN0cnUxIDwtIHdpdGgoaW1wdXRlZE1lZGlhblssdXNhYmxlX2l0ZW1zXSwgaW1wdXRlKGpvYi5pbnN0cnUxLCBtZWRpYW4pKQppbXB1dGVkTWVkaWFuJGNhcmVlci5pbnN0cnUxIDwtIHdpdGgoaW1wdXRlZE1lZGlhblssdXNhYmxlX2l0ZW1zXSwgaW1wdXRlKGNhcmVlci5pbnN0cnUxLCBtZWRpYW4pKQppbXB1dGVkTWVkaWFuJG1lZXRpbmcuaW50ZWdyMSA8LSB3aXRoKGltcHV0ZWRNZWRpYW5bLHVzYWJsZV9pdGVtc10sIGltcHV0ZShtZWV0aW5nLmludGVncjEsIG1lZGlhbikpCmltcHV0ZWRNZWRpYW4kaW50ZXJhY3QucG9zdDEgPC0gd2l0aChpbXB1dGVkTWVkaWFuWyx1c2FibGVfaXRlbXNdLCBpbXB1dGUoaW50ZXJhY3QucG9zdDEsIG1lZGlhbikpCgojIGNoZWNrIGJlZm9yZSBhZnRlcgp0YWJsZShpbXB1dGVkTWVkaWFuJHRpbWUuaW50ZWdyMSkKdGFibGUodXNhYmxlX2RhdGFfY29udGV4dCR0aW1lLmludGVncjEpCgp0YWJsZShpbXB1dGVkTWVkaWFuJGxpZmUuaW50cjEpCnRhYmxlKHVzYWJsZV9kYXRhX2NvbnRleHQkbGlmZS5pbnRyMSkKCnRhYmxlKGltcHV0ZWRNZWRpYW4ka25vd2xlZGdlLmluc3RydTEpCnRhYmxlKHVzYWJsZV9kYXRhX2NvbnRleHQka25vd2xlZGdlLmluc3RydTEpCgp0YWJsZShpbXB1dGVkTWVkaWFuJG1vbmV5Lmluc3RydTEpCnRhYmxlKHVzYWJsZV9kYXRhX2NvbnRleHQkbW9uZXkuaW5zdHJ1MSkKCnRhYmxlKGltcHV0ZWRNZWRpYW4kY2l0aXplbi5wb3N0MSkKdGFibGUodXNhYmxlX2RhdGFfY29udGV4dCRjaXRpemVuLnBvc3QxKQoKdGFibGUoaW1wdXRlZE1lZGlhbiRnbG9iYWxhY2Nlc3MucG9zdDEpCnRhYmxlKHVzYWJsZV9kYXRhX2NvbnRleHQkZ2xvYmFsYWNjZXNzLnBvc3QxKQoKCnRhYmxlKGltcHV0ZWRNZWRpYW4kZXhwZWN0Lm91Z2h0MSkKdGFibGUodXNhYmxlX2RhdGFfY29udGV4dCRleHBlY3Qub3VnaHQxKQoKdGFibGUoaW1wdXRlZE1lZGlhbiRqb2IuaW5zdHJ1MSkKdGFibGUodXNhYmxlX2RhdGFfY29udGV4dCRqb2IuaW5zdHJ1MSkKCnRhYmxlKGltcHV0ZWRNZWRpYW4kY2FyZWVyLmluc3RydTEpCnRhYmxlKHVzYWJsZV9kYXRhX2NvbnRleHQkY2FyZWVyLmluc3RydTEpCgp0YWJsZShpbXB1dGVkTWVkaWFuJG1lZXRpbmcuaW50ZWdyMSkKdGFibGUodXNhYmxlX2RhdGFfY29udGV4dCRtZWV0aW5nLmludGVncjEpCgp0YWJsZShpbXB1dGVkTWVkaWFuJGludGVyYWN0LnBvc3QxKQp0YWJsZSh1c2FibGVfZGF0YV9jb250ZXh0JGludGVyYWN0LnBvc3QxKQoKCmBgYAoKLSBTdWJzdGl0dXRlIGltcHV0ZWQgZGF0YSBmb3IgdGhlIGNvbW1vbiB2YXJpYWJsZXMgdG8gYmUgdXNlZCBpbiB0aGUgRmFjdG9yIEFuYWx5c2lzCgpgYGB7cn0KYWxsIDwtIGFsbFssIShjb2xuYW1lcyhhbGwpICVpbiUgdXNhYmxlX2l0ZW1zKV0KaW1wdXRlZE1lZGlhbiRDb250ZXh0IDwtIE5VTEwKc3VtKCEoY29sbmFtZXMoaW1wdXRlZE1lZGlhbikgJWluJSB1c2FibGVfaXRlbXMpKQphbGwgPC0gY2JpbmQoYWxsLGltcHV0ZWRNZWRpYW5bbWF0Y2gocm93bmFtZXMoaW1wdXRlZE1lZGlhbiksYWxsJFJlc3AuSUQpLF0pCmBgYAoKKipBZGQgc29tZSB1cGRhdGVzIHRoYXQgUmljaGkgZGlkIGluIERhdGUgN3RoIEp1bmUgMjAxOCoqCgpgYGB7ciBldmFsPUZBTFNFfQpPdGhlcl93YXlzX2FuZF9kZWdyZWVfcm9sZV93aXRoX3Jlc3BvbmRlbnRfSURzIDwtIHJlYWRfZXhjZWwoIk90aGVyLXdheXMtYW5kLWRlZ3JlZS1yb2xlLXdpdGgtcmVzcG9uZGVudC1JRHMueGxzeCIpCnN1bShPdGhlcl93YXlzX2FuZF9kZWdyZWVfcm9sZV93aXRoX3Jlc3BvbmRlbnRfSURzJFJlc3AuSUQgIT0gT3RoZXJfd2F5c19hbmRfZGVncmVlX3JvbGVfd2l0aF9yZXNwb25kZW50X0lEcyRSZXNwLklEX18xKQojIHRvIHJlcGxhY2UgCiMgbWF0Y2ggZm9yIHRoZSBOQSBkZWdyZWUucm9sZQoKbWF0Y2hfdXBkYXRlcyA8LSBtYXRjaChhbGwkUmVzcC5JRCxPdGhlcl93YXlzX2FuZF9kZWdyZWVfcm9sZV93aXRoX3Jlc3BvbmRlbnRfSURzJFJlc3AuSUQpCmFsbCRwcml2YXRlLmxlc3NvbnMxLm90aGVyLndheXNbbWF0Y2hfdXBkYXRlc10gPC0gT3RoZXJfd2F5c19hbmRfZGVncmVlX3JvbGVfd2l0aF9yZXNwb25kZW50X0lEcyRwcml2YXRlLmxlc3NvbnMxLm90aGVyLndheXMKYWxsJHN0dWR5LmhvbGlkYXkyLm90aGVyLndheXNbbWF0Y2hfdXBkYXRlc10gPC0gT3RoZXJfd2F5c19hbmRfZGVncmVlX3JvbGVfd2l0aF9yZXNwb25kZW50X0lEcyRzdHVkeS5ob2xpZGF5Mi5vdGhlci53YXlzCmFsbCR5ZWFyLnNlbS5hYnJvYWQzLm90aGVyLndheXNbbWF0Y2hfdXBkYXRlc10gPC0gT3RoZXJfd2F5c19hbmRfZGVncmVlX3JvbGVfd2l0aF9yZXNwb25kZW50X0lEcyR5ZWFyLnNlbS5hYnJvYWQzLm90aGVyLndheXMKYWxsJG9ubGluZS5jb3Vyc2U0Lm90aGVyLndheXNbbWF0Y2hfdXBkYXRlc10gPC0gT3RoZXJfd2F5c19hbmRfZGVncmVlX3JvbGVfd2l0aF9yZXNwb25kZW50X0lEcyRvbmxpbmUuY291cnNlNC5vdGhlci53YXlzCmFsbCRvdGhlcjUub3RoZXIud2F5c1ttYXRjaF91cGRhdGVzXSA8LSBPdGhlcl93YXlzX2FuZF9kZWdyZWVfcm9sZV93aXRoX3Jlc3BvbmRlbnRfSURzJG90aGVyNS5vdGhlci53YXlzCmFsbCRkZWdyZWUucm9sZVttYXRjaF91cGRhdGVzXSA8LSBPdGhlcl93YXlzX2FuZF9kZWdyZWVfcm9sZV93aXRoX3Jlc3BvbmRlbnRfSURzJGRlZ3JlZS5yb2xlCmBgYAoKIyMgU2F2ZSBpbXB1dGVkIGRhdGEKCmBgYHtyfQp3cml0ZS5jc3YoYWxsLCIwMi1kZXNjcmlwdGl2ZV9kYXRhL21lcmdlZF9maWx0ZXJlZF9pbXB1dGVkTWVkaWFuX2xpa2VydE51bWJlci5jc3YiLHJvdy5uYW1lcyA9IEZBTFNFKQpgYGAKCiMgQmFycGxvdCBvZiBsaWtlcnQgdmFyaWFibGVzCgpgYGB7ciBmaWcud2lkdGg9MjAsZmlnLmhlaWdodD0yMH0KYWxsX21lbHQgPC0gbWVsdChhbGwsaWQudmFycyA9IGMoIlJlc3AuSUQiLCJHZW5kZXIiLCJBZ2UiLCJwcm9mIiwiQ29udGV4dCIsInN0dWR5LnllYXIiKSwKICAgICAgICAgICAgICAgICAgICAgICAgbWVhc3VyZS52YXJzID0gbGlrZXJ0X3ZhcmlhYmxlczEpCgphbGxfbWVsdCR2YWx1ZSA8LSBmYWN0b3IoYWxsX21lbHQkdmFsdWUsbGV2ZWxzPWMoMSwyLDMsNCw1KSxsYWJlbHM9YygiU3Ryb25nbHkgZGlzYWdyZWUiLCJEaXNhZ3JlZSIsIk5vdCBzdXJlIiwiQWdyZWUiLCJTdHJvbmdseSBhZ3JlZSIpKQojIGRpbShhbGxfbWVsdCkKIyAzMjMqbGVuZ3RoKGxpa2VydF92YXJpYWJsZXMxKQoKYWxsX21lbHQgPC0gYWxsX21lbHQgJT4lIHNlcGFyYXRlKHZhcmlhYmxlLGludG89YygiaXRlbSIsInR5cGUiKSxzZXA9IlxcLiIscmVtb3ZlPUZBTFNFKQpnZ3Bsb3QoYWxsX21lbHQsYWVzKHg9dmFyaWFibGUsZmlsbD12YWx1ZSkpICsgZ2VvbV9iYXIocG9zaXRpb24gPSAic3RhY2siLGNvbG91cj0iYmxhY2siKSArIAogIGZhY2V0X2dyaWQoQ29udGV4dH50eXBlLHNjYWxlcyA9ICJmcmVlIikrdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSxheGlzLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9OCkpICsgZ2d0aXRsZSgiRmlsdGVyZWQgZGF0YXNldCIpICsgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoIiNjYTAwMjAiLCIjZjRhNTgyIiwiI2ZmZmZiZiIsIiNhYmQ5ZTkiLCIjMmM3YmI2IiwiZ3JleSIpKQoKZmlsdF9zdW0gPC0gYWxsX21lbHQgJT4lIGdyb3VwX2J5KENvbnRleHQsdmFyaWFibGUsdHlwZSx2YWx1ZSkgJT4lIGRwbHlyOjpzdW1tYXJpc2UoTmdyb3VwPWxlbmd0aCh2YWx1ZSkpCmdncGxvdChmaWx0X3N1bSxhZXMoeD12YWx1ZSx5PU5ncm91cCxjb2xvdXI9Q29udGV4dCxncm91cD1pbnRlcmFjdGlvbih2YXJpYWJsZSwgQ29udGV4dCkpKSArIGdlb21fbGluZSgpICsgZ2VvbV9wb2ludCgpICsgZmFjZXRfd3JhcCh+dHlwZSxzY2FsZXMgPSAiZnJlZSIpK3RoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpCgpgYGAKCiMjIEJhcnBsb3Qgb2YgRWR1Y2F0ZWQgYW5kIE5lY2Vzc2l0eSBpbiB0aGUgQXVzdHJhbGlhbiBhbmQgRXVyb3BlYW4gQ29udGV4dHMKCi0gKipFZHVjYXRlZCoqCgpgYGB7cn0KIyBhZGQgbnVtYmVycyBvbiB0aGUgYmFyCmVkdWNhdGVkIDwtIGFsbFthbGwkQ29udGV4dCAlaW4lIGMoIkdlcm1hbiBpbiBBdXN0cmFsaWEiLCJJdGFsaWFuIGluIEF1c3RyYWxpYSIpLF0KdGFibGUoZWR1Y2F0ZWQkZWR1Y2F0ZWQxLGVkdWNhdGVkJENvbnRleHQsdXNlTkE9ImFsd2F5cyIpCmVkdWNhdGVkJGVkdWNhdGVkMSA8LSBmYWN0b3IoZWR1Y2F0ZWQkZWR1Y2F0ZWQxLGxldmVscyA9IGMoMSwyLDMsNCw1KSxsYWJlbHM9YygiU3Ryb25nbHkgZGlzYWdyZWUiLCJEaXNhZ3JlZSIsIk5vdCBzdXJlIiwiQWdyZWUiLCJTdHJvbmdseSBhZ3JlZSIpKSAKCnRhYkVkdSA8LSB0KHRhYmxlKGVkdWNhdGVkJGVkdWNhdGVkMSxlZHVjYXRlZCRDb250ZXh0KSkKZ2dkZiA8LSBkYXRhLmZyYW1lKEVkdWNhdGVkID0gcmVwKGNvbG5hbWVzKHRhYkVkdSksZWFjaD0yKSwKICBOLlBhcnRpY2lwYW50cyA9IGFzLm51bWVyaWModGFiRWR1KSwKICBDb250ZXh0ID0gcmVwKHJvd25hbWVzKHRhYkVkdSksdGltZXM9NSkpCgoKZ2dwbG90KGdnZGYsYWVzKHg9RWR1Y2F0ZWQseT1OLlBhcnRpY2lwYW50cyxmaWxsPUNvbnRleHQpKSArIGdlb21fYmFyKHBvc2l0aW9uPSJkb2RnZSIsY29sb3VyPSJ3aGl0ZSIsc3RhdD0iaWRlbnRpdHkiKSAgKyBsYWJzKHk9Ik4gcGFydGljaXBhbnRzIikgKyBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgwLDM1LDEwKSxsaW1pdHM9YygwLDM1KSkgKyB0aGVtZV9idygpICsgZ2d0aXRsZSgiRWR1Y2F0ZWQgYnkgQ29udGV4dCIpKyAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IE4uUGFydGljaXBhbnRzKSwgaGp1c3Q9MC41LCB2anVzdD0tMC4yNSwgc2l6ZSA9IDIuNSxwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjkpKSAKZ2dwbG90KGdnZGYsYWVzKHg9Q29udGV4dCx5PU4uUGFydGljaXBhbnRzLGZpbGw9RWR1Y2F0ZWQpKSArIGdlb21fYmFyKHBvc2l0aW9uPSJkb2RnZSIsY29sb3VyPSJ3aGl0ZSIsc3RhdD0iaWRlbnRpdHkiKSAgKyBsYWJzKHk9Ik4gcGFydGljaXBhbnRzIikgKyBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgwLDM1LDEwKSxsaW1pdHM9YygwLDM1KSkgKyB0aGVtZV9idygpICsgZ2d0aXRsZSgiRWR1Y2F0ZWQgYnkgQ29udGV4dCIpKyAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IE4uUGFydGljaXBhbnRzKSwgaGp1c3Q9MC41LCB2anVzdD0tMC4yNSwgc2l6ZSA9IDIuNSxwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjkpKSAKYGBgCgotICoqTmVjZXNzaXR5KioKCmBgYHtyfQojIGFkZCBudW1iZXJzIG9uIHRoZSBiYXIKbmVjZXNzaXR5IDwtIGFsbFthbGwkQ29udGV4dCAlaW4lIGMoIkVuZ2xpc2ggaW4gR2VybWFueSIsIkVuZ2xpc2ggaW4gSXRhbHkiKSxdCnRhYmxlKG5lY2Vzc2l0eSRuZWNlc3NpdHkxLG5lY2Vzc2l0eSRDb250ZXh0LHVzZU5BPSJhbHdheXMiKQpuZWNlc3NpdHkkbmVjZXNzaXR5MSA8LSBmYWN0b3IobmVjZXNzaXR5JG5lY2Vzc2l0eTEsbGV2ZWxzID0gYygxLDIsMyw0LDUpLGxhYmVscz1jKCJTdHJvbmdseSBkaXNhZ3JlZSIsIkRpc2FncmVlIiwiTm90IHN1cmUiLCJBZ3JlZSIsIlN0cm9uZ2x5IGFncmVlIikpIAoKdGFiTmVjIDwtIHQodGFibGUobmVjZXNzaXR5JG5lY2Vzc2l0eTEsbmVjZXNzaXR5JENvbnRleHQsdXNlTkEgPSAiYWx3YXlzIikpWy0zLF0KZ2dkZiA8LSBkYXRhLmZyYW1lKE5lY2Vzc2l0eSA9IHJlcChjb2xuYW1lcyh0YWJOZWMpLGVhY2g9MiksCiAgTi5QYXJ0aWNpcGFudHMgPSBhcy5udW1lcmljKHRhYk5lYyksCiAgQ29udGV4dCA9IHJlcChyb3duYW1lcyh0YWJOZWMpLHRpbWVzPTYpKQoKCmdncGxvdChnZ2RmLGFlcyh4PU5lY2Vzc2l0eSx5PU4uUGFydGljaXBhbnRzLGZpbGw9Q29udGV4dCkpICsgZ2VvbV9iYXIocG9zaXRpb249ImRvZGdlIixjb2xvdXI9IndoaXRlIixzdGF0PSJpZGVudGl0eSIpICArIGxhYnMoeT0iTiBwYXJ0aWNpcGFudHMiKSArIHNjYWxlX3lfY29udGludW91cyhicmVha3M9c2VxKDAsNDAsMTApLGxpbWl0cz1jKDAsNDApKSArIHRoZW1lX2J3KCkgKyBnZ3RpdGxlKCJOZWNlc3NpdHkgYnkgQ29udGV4dCIpKyAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IE4uUGFydGljaXBhbnRzKSwgaGp1c3Q9MC41LCB2anVzdD0tMC4yNSwgc2l6ZSA9IDIuNSxwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjkpKSAKZ2dwbG90KGdnZGYsYWVzKHg9Q29udGV4dCx5PU4uUGFydGljaXBhbnRzLGZpbGw9TmVjZXNzaXR5KSkgKyBnZW9tX2Jhcihwb3NpdGlvbj0iZG9kZ2UiLGNvbG91cj0id2hpdGUiLHN0YXQ9ImlkZW50aXR5IikgICsgbGFicyh5PSJOIHBhcnRpY2lwYW50cyIpICsgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcz1zZXEoMCwzNSwxMCksbGltaXRzPWMoMCwzNSkpICsgdGhlbWVfYncoKSArIGdndGl0bGUoIk5lY2Vzc2l0eSBieSBDb250ZXh0IikrICBnZW9tX3RleHQoYWVzKGxhYmVsID0gTi5QYXJ0aWNpcGFudHMpLCBoanVzdD0wLjUsIHZqdXN0PS0wLjI1LCBzaXplID0gMi41LHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuOSkpIApgYGAKCiMgQ29ycmVsYXRpb24gcGxvdCBvZiBpdGVtcyBieSBjb250ZXh0CgojIyBJdGFsaWFuIGluIEF1c3RyYWxpYQoKYGBge3IgY29yX2l0YWxpYW5faW5fYXVzdHJhbGlhLGZpZy53aWR0aD0xNSxmaWcuaGVpZ2h0PTE1fQpjb3YgPC0gY29yKGZpbHRlcmVkX2NvbnZbZmlsdGVyZWRfY29udiRDb250ZXh0ID09ICJJdGFsaWFuIGluIEF1c3RyYWxpYSIsbGlrZXJ0X3ZhcmlhYmxlczFbIShsaWtlcnRfdmFyaWFibGVzMSAlaW4lICJuZWNlc3NpdHkxIildXSxtZXRob2QgPSAicGVhcnNvbiIsdXNlPSJwYWlyd2lzZS5jb21wbGV0ZS5vYnMiKQpkYXRhX2Nvcl9pdGFfaW5fYXUgPC0gZGF0YS5mcmFtZShjb3JfaXRhX2luX2F1PWNvdltsb3dlci50cmkoY292LCBkaWFnID0gVFJVRSldLAogICAgICAgICAgICAgICAgdmFyMSA9IHJvd25hbWVzKGNvdilbdW5saXN0KHQobWFwcGx5KCI6IiwgMTpucm93KGNvdiksIG5yb3coY292KSkpWzEsXSldLAogICAgICAgICAgICAgICAgdmFyMiA9IHJlcChjb2xuYW1lcyhjb3YpLHRpbWVzPXJldihzZXEobnJvdyhjb3YpOjEpKSkpCgpyb3dfaW5mb3MgPC0gZGF0YS5mcmFtZShWYXJpYWJsZXM9c2FwcGx5KHN0cnNwbGl0KGNvbG5hbWVzKGNvdiksc3BsaXQ9IlxcLiIpLGZ1bmN0aW9uKHgpIHhbMl0pKQpyb3dfaW5mb3MkVmFyaWFibGVzIDwtIGFzLmNoYXJhY3Rlcihyb3dfaW5mb3MkVmFyaWFibGVzKQpyb3duYW1lcyhyb3dfaW5mb3MpIDwtIHJvd25hbWVzKGNvdikKcm93X2luZm9zJFZhcmlhYmxlc1t3aGljaChpcy5uYShyb3dfaW5mb3MkVmFyaWFibGVzKSldIDwtIGMoImVkdWNhdGVkIikKcm93X2luZm9zIDwtIHJvd19pbmZvc1tvcmRlcihyb3dfaW5mb3MkVmFyaWFibGVzKSwsZHJvcD1GQUxTRV0KCmFubl9jb2xfd2lkZSA8LSBkYXRhLmZyYW1lKFZhcmlhYmxlPXVuaXF1ZShyb3dfaW5mb3MkVmFyaWFibGVzKSkKYW5uX2NvbG9yc193aWRlIDwtIGxpc3QoVmFyaWFibGVzPWMoY29tbTE9IiNiZDAwMjYiLGVkdWNhdGVkPSIjYjM1ODA2IiwgaWQxPSIjZjZlOGMzIixpbnN0cnUxPSIjMzU5NzhmIixpbnRlZ3IxPSIjMzg2Y2IwIixpbnRyMT0iI2ZmZmY5OSIsb3VnaHQxPSJncmV5Iixwb3N0MT0iYmxhY2siLHByb2YxPSJwaW5rIikpCgojcGhlYXRtYXAoY292LCBtYWluID0gIkl0YWxpYW4gaW4gQXVzdHJhbGlhIixhbm5vdGF0aW9uX25hbWVzX3JvdyA9IEZBTFNFLGNsdXN0ZXJfY29scz1UUlVFLGNsdXN0ZXJfcm93cz1UUlVFLGFubm90YXRpb25fY29sID0gcm93X2luZm9zWywxLGRyb3A9RkFMU0VdLCBhbm5vdGF0aW9uX3JvdyA9IHJvd19pbmZvc1ssMSxkcm9wPUZBTFNFXSwgIGFubm90YXRpb25fY29sb3JzID0gYW5uX2NvbG9yc193aWRlLGJyZWFrcz1zZXEoLTEsMSwwLjIpLGNvbD1jKCIjNjcwMDFmIiwiI2IyMTgyYiIsIiNkNjYwNGQiLCIjZjRhNTgyIiwiI2ZkZGJjNyIsIiNmN2Y3ZjciLCIjZDFlNWYwIiwiIzkyYzVkZSIsIiM0MzkzYzMiLCIjMjE2NmFjIiwiIzA1MzA2MSIpLHNob3dfY29sbmFtZXMgPSBGQUxTRSx3aWR0aCA9IDcsaGVpZ2h0ID0gNykKIyMjIyMjIyMjIyMjIyMjIyMjIwoKZGlhZyhjb3YpIDwtIE5BCnBoZWF0bWFwKGNvdiwgbWFpbiA9ICJJdGFsaWFuIGluIEF1c3RyYWxpYSIsYW5ub3RhdGlvbl9uYW1lc19yb3cgPSBGQUxTRSxjbHVzdGVyX2NvbHM9VFJVRSxjbHVzdGVyX3Jvd3M9VFJVRSxhbm5vdGF0aW9uX2NvbCA9IHJvd19pbmZvc1ssMSxkcm9wPUZBTFNFXSwgYW5ub3RhdGlvbl9yb3cgPSByb3dfaW5mb3NbLDEsZHJvcD1GQUxTRV0KLCAgYW5ub3RhdGlvbl9jb2xvcnMgPSBhbm5fY29sb3JzX3dpZGUsc2hvd19jb2xuYW1lcyA9IEZBTFNFLGJyZWFrcyA9IHNlcSgtMC42LDAuNyxsZW5ndGgub3V0ID0gNTApLHdpZHRoID0gNyxoZWlnaHQgPSA3LGNvbG9yPWNvbG9yUmFtcFBhbGV0dGUoYnJld2VyLnBhbChuID0gNywgbmFtZSA9ICJSZEJ1IikpKDUwKSkKCmNvdl9JdGFBdXMgPC0gY292CmBgYAoKIyMgR2VybWFuIGluIEF1c3RyYWxpYQoKYGBge3IgY29yX2dlcm1hbl9pbl9hdXN0cmFsaWEsZmlnLndpZHRoPTE1LGZpZy5oZWlnaHQ9MTV9CmNvdiA8LSBjb3IoZmlsdGVyZWRfY29udltmaWx0ZXJlZF9jb252JENvbnRleHQgPT0gIkdlcm1hbiBpbiBBdXN0cmFsaWEiLGxpa2VydF92YXJpYWJsZXMxWyEobGlrZXJ0X3ZhcmlhYmxlczEgJWluJSAibmVjZXNzaXR5MSIpXV0sbWV0aG9kID0gInBlYXJzb24iLHVzZT0icGFpcndpc2UuY29tcGxldGUub2JzIikKZGF0YV9jb3JfZ2VybV9pbl9hdSA8LSBkYXRhLmZyYW1lKGNvcl9nZXJtX2luX2F1PWNvdltsb3dlci50cmkoY292LCBkaWFnID0gVFJVRSldLAogICAgICAgICAgICAgICAgdmFyMSA9IHJvd25hbWVzKGNvdilbdW5saXN0KHQobWFwcGx5KCI6IiwgMTpucm93KGNvdiksIG5yb3coY292KSkpWzEsXSldLAogICAgICAgICAgICAgICAgdmFyMiA9IHJlcChjb2xuYW1lcyhjb3YpLHRpbWVzPXJldihzZXEobnJvdyhjb3YpOjEpKSkpCgoKCnJvd19pbmZvcyA8LSBkYXRhLmZyYW1lKFZhcmlhYmxlcz1zYXBwbHkoc3Ryc3BsaXQoY29sbmFtZXMoY292KSxzcGxpdD0iXFwuIiksZnVuY3Rpb24oeCkgeFsyXSkpCnJvd19pbmZvcyRWYXJpYWJsZXMgPC0gYXMuY2hhcmFjdGVyKHJvd19pbmZvcyRWYXJpYWJsZXMpCnJvd25hbWVzKHJvd19pbmZvcykgPC0gcm93bmFtZXMoY292KQpyb3dfaW5mb3MkVmFyaWFibGVzW3doaWNoKGlzLm5hKHJvd19pbmZvcyRWYXJpYWJsZXMpKV0gPC0gYygiZWR1Y2F0ZWQiKQpyb3dfaW5mb3MgPC0gcm93X2luZm9zW29yZGVyKHJvd19pbmZvcyRWYXJpYWJsZXMpLCxkcm9wPUZBTFNFXQoKYW5uX2NvbF93aWRlIDwtIGRhdGEuZnJhbWUoVmFyaWFibGU9dW5pcXVlKHJvd19pbmZvcyRWYXJpYWJsZXMpKQphbm5fY29sb3JzX3dpZGUgPC0gbGlzdChWYXJpYWJsZXM9Yyhjb21tMT0iI2JkMDAyNiIsZWR1Y2F0ZWQ9IiNiMzU4MDYiLCBpZDE9IiNmNmU4YzMiLGluc3RydTE9IiMzNTk3OGYiLGludGVncjE9IiMzODZjYjAiLGludHIxPSIjZmZmZjk5IixvdWdodDE9ImdyZXkiLHBvc3QxPSJibGFjayIscHJvZjE9InBpbmsiKSkKCmRpYWcoY292KSA8LSBOQQpwaGVhdG1hcChjb3YsIG1haW4gPSAiR2VybWFuIGluIEF1c3RyYWxpYSIsYW5ub3RhdGlvbl9uYW1lc19yb3cgPSBGQUxTRSxjbHVzdGVyX2NvbHM9VFJVRSxjbHVzdGVyX3Jvd3M9VFJVRSxhbm5vdGF0aW9uX2NvbCA9IHJvd19pbmZvc1ssMSxkcm9wPUZBTFNFXSwgYW5ub3RhdGlvbl9yb3cgPSByb3dfaW5mb3NbLDEsZHJvcD1GQUxTRV0KLCAgYW5ub3RhdGlvbl9jb2xvcnMgPSBhbm5fY29sb3JzX3dpZGUsc2hvd19jb2xuYW1lcyA9IEZBTFNFLGJyZWFrcyA9IHNlcSgtMC42LDAuNyxsZW5ndGgub3V0ID0gNTApLHdpZHRoID0gNyxoZWlnaHQgPSA3LGNvbG9yPWNvbG9yUmFtcFBhbGV0dGUoYnJld2VyLnBhbChuID0gNywgbmFtZSA9ICJSZEJ1IikpKDUwKSkKCiMgCmNvdl9HZXJtQXVzIDwtIGNvdgpgYGAKCiMjIEVuZ2xpc2ggaW4gR2VybWFueQoKYGBge3IgY29yX2VuZ2xpc2hfaW5fZ2VybWFueSxmaWcud2lkdGg9MTUsZmlnLmhlaWdodD0xNX0KY292IDwtIGNvcihmaWx0ZXJlZF9jb252W2ZpbHRlcmVkX2NvbnYkQ29udGV4dCA9PSAiRW5nbGlzaCBpbiBHZXJtYW55IixsaWtlcnRfdmFyaWFibGVzMVshKGxpa2VydF92YXJpYWJsZXMxICVpbiUgYygicmVjb25uZWN0LmNvbW0xIiwgICAgInNwZWFrZXJzbWVsYi5jb21tMSIsImNvbWVjbG9zZXIuY29tbTEiLCJlZHVjYXRlZDEiKSldXSxtZXRob2QgPSAicGVhcnNvbiIsdXNlPSJwYWlyd2lzZS5jb21wbGV0ZS5vYnMiKQpkYXRhX2Nvcl9lbmdfaW5fZ2VybSA8LSBkYXRhLmZyYW1lKGNvcl9lbmdfaW5fZ2VybT1jb3ZbbG93ZXIudHJpKGNvdiwgZGlhZyA9IFRSVUUpXSwKICAgICAgICAgICAgICAgIHZhcjEgPSByb3duYW1lcyhjb3YpW3VubGlzdCh0KG1hcHBseSgiOiIsIDE6bnJvdyhjb3YpLCBucm93KGNvdikpKVsxLF0pXSwKICAgICAgICAgICAgICAgIHZhcjIgPSByZXAoY29sbmFtZXMoY292KSx0aW1lcz1yZXYoc2VxKG5yb3coY292KToxKSkpKQoKCnJvd19pbmZvcyA8LSBkYXRhLmZyYW1lKFZhcmlhYmxlcz1zYXBwbHkoc3Ryc3BsaXQoY29sbmFtZXMoY292KSxzcGxpdD0iXFwuIiksZnVuY3Rpb24oeCkgeFsyXSkpCnJvd19pbmZvcyRWYXJpYWJsZXMgPC0gYXMuY2hhcmFjdGVyKHJvd19pbmZvcyRWYXJpYWJsZXMpCnJvd25hbWVzKHJvd19pbmZvcykgPC0gcm93bmFtZXMoY292KQpyb3dfaW5mb3MkVmFyaWFibGVzW3doaWNoKGlzLm5hKHJvd19pbmZvcyRWYXJpYWJsZXMpKV0gPC0gYygibmVjZXNzaXR5IikKcm93X2luZm9zIDwtIHJvd19pbmZvc1tvcmRlcihyb3dfaW5mb3MkVmFyaWFibGVzKSwsZHJvcD1GQUxTRV0KCmFubl9jb2xfd2lkZSA8LSBkYXRhLmZyYW1lKFZhcmlhYmxlPXVuaXF1ZShyb3dfaW5mb3MkVmFyaWFibGVzKSkKYW5uX2NvbG9yc193aWRlIDwtIGxpc3QoVmFyaWFibGVzPWMoaWQxPSIjZjZlOGMzIixuZWNlc3NpdHk9IiNiMzU4MDYiLGluc3RydTE9IiMzNTk3OGYiLGludGVncjE9IiMzODZjYjAiLGludHIxPSIjZmZmZjk5IixvdWdodDE9ImdyZXkiLHBvc3QxPSJibGFjayIscHJvZjE9InBpbmsiKSkKCmRpYWcoY292KSA8LSBOQQpwaGVhdG1hcChjb3YsIG1haW4gPSAiRW5nbGlzaCBpbiBHZXJtYW55Iixhbm5vdGF0aW9uX25hbWVzX3JvdyA9IEZBTFNFLGNsdXN0ZXJfY29scz1UUlVFLGNsdXN0ZXJfcm93cz1UUlVFLGFubm90YXRpb25fY29sID0gcm93X2luZm9zWywxLGRyb3A9RkFMU0VdLCBhbm5vdGF0aW9uX3JvdyA9IHJvd19pbmZvc1ssMSxkcm9wPUZBTFNFXQosICBhbm5vdGF0aW9uX2NvbG9ycyA9IGFubl9jb2xvcnNfd2lkZSxzaG93X2NvbG5hbWVzID0gRkFMU0UsYnJlYWtzID0gc2VxKC0wLjYsMC43LGxlbmd0aC5vdXQgPSA1MCksd2lkdGggPSA3LGhlaWdodCA9IDcsY29sb3I9Y29sb3JSYW1wUGFsZXR0ZShicmV3ZXIucGFsKG4gPSA3LCBuYW1lID0gIlJkQnUiKSkoNTApKQoKY292X0VuZ0dlcm0gPC0gY292CmBgYAoKIyMgRW5nbGlzaCBpbiBJdGFseQoKYGBge3IgY29yX2VuZ2xpc2hfaW5faXRhbHksZmlnLndpZHRoPTE1LGZpZy5oZWlnaHQ9MTV9CmNvdiA8LSBjb3IoZmlsdGVyZWRfY29udltmaWx0ZXJlZF9jb252JENvbnRleHQgPT0gIkVuZ2xpc2ggaW4gSXRhbHkiLGxpa2VydF92YXJpYWJsZXMxWyEobGlrZXJ0X3ZhcmlhYmxlczEgJWluJSBjKCJyZWNvbm5lY3QuY29tbTEiLCJzcGVha2Vyc21lbGIuY29tbTEiLCJjb21lY2xvc2VyLmNvbW0xIiwiZWR1Y2F0ZWQxIikpXV0sbWV0aG9kID0gInBlYXJzb24iLHVzZT0icGFpcndpc2UuY29tcGxldGUub2JzIikKZGF0YV9jb3JfZW5nX2luX2l0YSA8LSBkYXRhLmZyYW1lKGNvcl9lbmdfaW5faXRhPWNvdltsb3dlci50cmkoY292LCBkaWFnID0gVFJVRSldLAogICAgICAgICAgICAgICAgdmFyMSA9IHJvd25hbWVzKGNvdilbdW5saXN0KHQobWFwcGx5KCI6IiwgMTpucm93KGNvdiksIG5yb3coY292KSkpWzEsXSldLAogICAgICAgICAgICAgICAgdmFyMiA9IHJlcChjb2xuYW1lcyhjb3YpLHRpbWVzPXJldihzZXEobnJvdyhjb3YpOjEpKSkpCgoKcm93X2luZm9zIDwtIGRhdGEuZnJhbWUoVmFyaWFibGVzPXNhcHBseShzdHJzcGxpdChjb2xuYW1lcyhjb3YpLHNwbGl0PSJcXC4iKSxmdW5jdGlvbih4KSB4WzJdKSkKcm93X2luZm9zJFZhcmlhYmxlcyA8LSBhcy5jaGFyYWN0ZXIocm93X2luZm9zJFZhcmlhYmxlcykKcm93bmFtZXMocm93X2luZm9zKSA8LSByb3duYW1lcyhjb3YpCnJvd19pbmZvcyRWYXJpYWJsZXNbd2hpY2goaXMubmEocm93X2luZm9zJFZhcmlhYmxlcykpXSA8LSAibmVjZXNzaXR5Igpyb3dfaW5mb3MgPC0gcm93X2luZm9zW29yZGVyKHJvd19pbmZvcyRWYXJpYWJsZXMpLCxkcm9wPUZBTFNFXQoKYW5uX2NvbF93aWRlIDwtIGRhdGEuZnJhbWUoVmFyaWFibGU9dW5pcXVlKHJvd19pbmZvcyRWYXJpYWJsZXMpKQphbm5fY29sb3JzX3dpZGUgPC0gbGlzdChWYXJpYWJsZXM9Yyhjb21tMT0iI2JkMDAyNiIsbmVjZXNzaXR5PSIjYjM1ODA2IiwgaWQxPSIjZjZlOGMzIixpbnN0cnUxPSIjMzU5NzhmIixpbnRlZ3IxPSIjMzg2Y2IwIixpbnRyMT0iI2ZmZmY5OSIsb3VnaHQxPSJncmV5Iixwb3N0MT0iYmxhY2siLHByb2YxPSJwaW5rIikpCgpkaWFnKGNvdikgPC0gTkEKcGhlYXRtYXAoY292LCBtYWluID0gIkVuZ2xpc2ggaW4gSXRhbHkiLGFubm90YXRpb25fbmFtZXNfcm93ID0gRkFMU0UsY2x1c3Rlcl9jb2xzPVRSVUUsY2x1c3Rlcl9yb3dzPVRSVUUsYW5ub3RhdGlvbl9jb2wgPSByb3dfaW5mb3NbLDEsZHJvcD1GQUxTRV0sIGFubm90YXRpb25fcm93ID0gcm93X2luZm9zWywxLGRyb3A9RkFMU0VdCiwgIGFubm90YXRpb25fY29sb3JzID0gYW5uX2NvbG9yc193aWRlLHNob3dfY29sbmFtZXMgPSBGQUxTRSxicmVha3MgPSBzZXEoLTAuNiwwLjcsbGVuZ3RoLm91dCA9IDUwKSx3aWR0aCA9IDcsaGVpZ2h0ID0gNyxjb2xvcj1jb2xvclJhbXBQYWxldHRlKGJyZXdlci5wYWwobiA9IDcsIG5hbWUgPSAiUmRCdSIpKSg1MCkpCgojIApjb3ZfRW5nSXRhIDwtIGNvdgpgYGAKCiMjIENvcnJlbGF0aW9uIGJldHdlZW4gY29ycmVsYXRpb24gaW4gdGhlIGRpZmZlcmVudCBjb250ZXh0cwoKV2Ugd2lsbCBwZXJmb3JtIGFuIGV4cGxvcmF0b3J5IEZBIGNvbWJpbmluZyBhbGwgdGhlIGNvbnRleHRzIHRvZ2V0aGVyLiBUaGlzIG1lYW5zIHRoYXQgd2UgYXJlIGFzc3VtaW5nIHRoYXQgdGhlIGNvcnJlbGF0aW9uIGJldHdlZW4gaXRlbXMgYWNyb3NzIGNvbnRleHQgaGFzIHRoZSBzYW1lIGRpcmVjdGlvbiAoZG9lcyBub3QgaGFwcGVuIHRoYXQgY29yKGl0ZW0xLGl0ZW0yKV9jb250ZXh0MSA+IDAgYW5kIGNvcihpdGVtMSxpdGVtMilfY29udGV4dDIgPCAwKS4gCgpgYGB7ciBmaWcud2lkdGg9MTAsZmlnLmhlaWdodD0xMH0KY29tbW9uIDwtIHJvd25hbWVzKGNvdl9FbmdJdGEpW3Jvd25hbWVzKGNvdl9FbmdJdGEpICVpbiUgcm93bmFtZXMoY292X0l0YUF1cyldCnN1bShyb3duYW1lcyhjb3ZfRW5nSXRhKSAhPSByb3duYW1lcyhjb3ZfRW5nR2VybSkpCnN1bShyb3duYW1lcyhjb3ZfRW5nSXRhKSAhPSByb3duYW1lcyhjb3ZfR2VybUF1cykpCnN1bShyb3duYW1lcyhjb3ZfRW5nSXRhKSAhPSByb3duYW1lcyhjb3ZfSXRhQXVzKSkKc3VtKHJvd25hbWVzKGNvdl9HZXJtQXVzKSAhPSByb3duYW1lcyhjb3ZfSXRhQXVzKSkKCmNvbW1vbl9FbmdJdGEgPC0gY292X0VuZ0l0YVtyb3duYW1lcyhjb3ZfRW5nSXRhKSAlaW4lIGNvbW1vbixjb2xuYW1lcyhjb3ZfRW5nSXRhKSAlaW4lIGNvbW1vbl0KY29tbW9uX0VuZ0dlcm0gPC0gY292X0VuZ0dlcm1bcm93bmFtZXMoY292X0VuZ0dlcm0pICVpbiUgY29tbW9uLGNvbG5hbWVzKGNvdl9FbmdHZXJtKSAlaW4lIGNvbW1vbl0KY29tbW9uX0dlcm1BdXMgPC0gY292X0dlcm1BdXNbcm93bmFtZXMoY292X0dlcm1BdXMpICVpbiUgY29tbW9uLGNvbG5hbWVzKGNvdl9HZXJtQXVzKSAlaW4lIGNvbW1vbl0KY29tbW9uX0l0YUF1cyA8LSBjb3ZfSXRhQXVzW3Jvd25hbWVzKGNvdl9JdGFBdXMpICVpbiUgY29tbW9uLGNvbG5hbWVzKGNvdl9JdGFBdXMpICVpbiUgY29tbW9uXQoKc3VtKHJvd25hbWVzKGNvbW1vbl9FbmdJdGEpICE9IGNvbG5hbWVzKGNvbW1vbl9FbmdJdGEpKQpzdW0ocm93bmFtZXMoY29tbW9uX0VuZ0dlcm0pICE9IGNvbG5hbWVzKGNvbW1vbl9FbmdHZXJtKSkKc3VtKHJvd25hbWVzKGNvbW1vbl9HZXJtQXVzKSAhPSBjb2xuYW1lcyhjb21tb25fR2VybUF1cykpCnN1bShyb3duYW1lcyhjb21tb25fSXRhQXVzKSAhPSBjb2xuYW1lcyhjb21tb25fSXRhQXVzKSkKCgpwYXIobWZyb3c9YygyLDMpKQpwbG90KGNvbW1vbl9FbmdJdGEsY29tbW9uX0VuZ0dlcm0pCmFibGluZShoPWMoMCwwLjMpLHY9YygwLDAuMyksbHR5PTIsY29sID0gImRhcmsgcmVkIikKYWJsaW5lKGE9MCxiPTEsbHR5PTIsY29sID0gImRhcmsgcmVkIikKcGxvdChjb21tb25fRW5nSXRhLGNvbW1vbl9HZXJtQXVzKQphYmxpbmUoaD1jKDAsMC4zKSx2PWMoMCwwLjMpLGx0eT0yLGNvbCA9ICJkYXJrIHJlZCIpCmFibGluZShhPTAsYj0xLGx0eT0yLGNvbCA9ICJkYXJrIHJlZCIpCnBsb3QoY29tbW9uX0VuZ0l0YSxjb21tb25fSXRhQXVzKQphYmxpbmUoaD1jKDAsMC4zKSx2PWMoMCwwLjMpLGx0eT0yLGNvbCA9ICJkYXJrIHJlZCIpCmFibGluZShhPTAsYj0xLGx0eT0yLGNvbCA9ICJkYXJrIHJlZCIpCgpwbG90KGNvbW1vbl9FbmdHZXJtLGNvbW1vbl9HZXJtQXVzKQphYmxpbmUoaD1jKDAsMC4zKSx2PWMoMCwwLjMpLGx0eT0yLGNvbCA9ICJkYXJrIHJlZCIpCmFibGluZShhPTAsYj0xLGx0eT0yLGNvbCA9ICJkYXJrIHJlZCIpCnBsb3QoY29tbW9uX0VuZ0dlcm0sY29tbW9uX0l0YUF1cykKYWJsaW5lKGg9YygwLDAuMyksdj1jKDAsMC4zKSxsdHk9Mixjb2wgPSAiZGFyayByZWQiKQphYmxpbmUoYT0wLGI9MSxsdHk9Mixjb2wgPSAiZGFyayByZWQiKQoKcGxvdChjb21tb25fR2VybUF1cyxjb21tb25fSXRhQXVzKQphYmxpbmUoaD1jKDAsMC4zKSx2PWMoMCwwLjMpLGx0eT0yLGNvbCA9ICJkYXJrIHJlZCIpCmFibGluZShhPTAsYj0xLGx0eT0yLGNvbCA9ICJkYXJrIHJlZCIpCgojIExhcmdlc3QgZGlmZmVyZW5jZXMKbG93X0VuZ0dlcm0gPC0gbG93ZXIudHJpKGNvbW1vbl9FbmdHZXJtKQpjb21tb25fRW5nR2VybVshbG93X0VuZ0dlcm1dIDwtIE5BCmNvbW1vbl9HZXJtQXVzWyEobG93ZXIudHJpKGNvbW1vbl9HZXJtQXVzKSldIDwtIE5BCmNvbW1vbl9JdGFBdXNbIShsb3dlci50cmkoY29tbW9uX0l0YUF1cykpXSA8LSBOQQpjb21tb25fRW5nSXRhWyEobG93ZXIudHJpKGNvbW1vbl9FbmdJdGEpKV0gPC0gTkEKCgptYXQgPC0gZGF0YS5mcmFtZShjb21tb25fRW5nR2VybT1jKGNvbW1vbl9FbmdHZXJtKSwKICAgICAgICAgICAgICAgICAgY29tbW9uX0VuZ0l0YT1jKGNvbW1vbl9FbmdJdGEpLAogICAgICAgICAgICAgICAgICBjb21tb25fR2VybUF1cyA9IGMoY29tbW9uX0dlcm1BdXMpLAogICAgICAgICAgICAgICAgICBjb21tb25fSXRhQXVzID0gYyhjb21tb25fSXRhQXVzKSwKICAgICAgICAgICAgICAgICAgY29tcGFyZSA9IHBhc3RlKHJvd25hbWVzKGNvbW1vbl9FbmdHZXJtKSxjb2xuYW1lcyhjb21tb25fRW5nR2VybSksc2VwPSIuIikpICU+JQogIGZpbHRlcighaXMubmEoY29tbW9uX0VuZ0dlcm0pKSAlPiUKICBzZXBhcmF0ZShjb21wYXJlLGludG89YygiaXRlbTEiLCJ2YXJpYWJsZTEiLCJpdGVtMiIsInZhcmlhYmxlMiIpLHJlbW92ZT1GQUxTRSxzZXA9IlsuXSIpICU+JQogIHVuaXRlKGdyb3VwLHZhcmlhYmxlMSx2YXJpYWJsZTIsc2VwPSIuIikKCmxpYnJhcnkoZ2dyZXBlbCkKZ2dwbG90KG1hdCxhZXMoeD1jb21tb25fRW5nR2VybSx5PWNvbW1vbl9HZXJtQXVzLGxhYmVsPWNvbXBhcmUsY29sb3VyPWdyb3VwKSkgKyBnZW9tX3BvaW50KGFscGhhPTAuNSxzaXplPTAuOCkgKyBnZW9tX3RleHQoc2l6ZT0yKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0PWMoMCwwLjMpLGxpbmV0eXBlPSJkb3R0ZWQiLGNvbG91cj0iZGFyayByZWQiKSArCmdlb21fdmxpbmUoeGludGVyY2VwdD1jKDAsMC4zKSxsaW5ldHlwZT0iZG90dGVkIixjb2xvdXI9ImRhcmsgcmVkIikKCgpnZ3Bsb3QobWF0LGFlcyh4PWNvbW1vbl9FbmdHZXJtLHk9Y29tbW9uX0l0YUF1cyxsYWJlbD1jb21wYXJlLGNvbG91cj1ncm91cCkpICsgZ2VvbV9wb2ludChhbHBoYT0wLjUsc2l6ZT0wLjgpICsgZ2VvbV90ZXh0KHNpemU9MikgKwogIGdlb21faGxpbmUoeWludGVyY2VwdD1jKDAsMC4zKSxsaW5ldHlwZT0iZG90dGVkIixjb2xvdXI9ImRhcmsgcmVkIikgKwpnZW9tX3ZsaW5lKHhpbnRlcmNlcHQ9YygwLDAuMyksbGluZXR5cGU9ImRvdHRlZCIsY29sb3VyPSJkYXJrIHJlZCIpCgpnZ3Bsb3QobWF0LGFlcyh4PWNvbW1vbl9FbmdHZXJtLHk9Y29tbW9uX0VuZ0l0YSxsYWJlbD1jb21wYXJlLGNvbG91cj1ncm91cCkpICsgZ2VvbV9wb2ludChhbHBoYT0wLjUsc2l6ZT0wLjgpICsgZ2VvbV90ZXh0KHNpemU9MikgKwogIGdlb21faGxpbmUoeWludGVyY2VwdD1jKDAsMC4zKSxsaW5ldHlwZT0iZG90dGVkIixjb2xvdXI9ImRhcmsgcmVkIikgKwpnZW9tX3ZsaW5lKHhpbnRlcmNlcHQ9YygwLDAuMyksbGluZXR5cGU9ImRvdHRlZCIsY29sb3VyPSJkYXJrIHJlZCIpCgpgYGAKCgojIyBBbGwgY29udGV4dCB0b2dldGhlcgoKYGBge3IgY29yX2FsbF9jb250ZXh0c30KY292IDwtIGNvcihmaWx0ZXJlZF9jb252WyxsaWtlcnRfdmFyaWFibGVzMV0sbWV0aG9kID0gInBlYXJzb24iLHVzZT0icGFpcndpc2UuY29tcGxldGUub2JzIikKCnJvd19pbmZvcyA8LSBkYXRhLmZyYW1lKFZhcmlhYmxlcz1zYXBwbHkoc3Ryc3BsaXQoY29sbmFtZXMoY292KSxzcGxpdD0iXFwuIiksZnVuY3Rpb24oeCkgeFsyXSkpCnJvd19pbmZvcyRWYXJpYWJsZXMgPC0gYXMuY2hhcmFjdGVyKHJvd19pbmZvcyRWYXJpYWJsZXMpCnJvd25hbWVzKHJvd19pbmZvcykgPC0gcm93bmFtZXMoY292KQpyb3dfaW5mb3MkVmFyaWFibGVzW3doaWNoKGlzLm5hKHJvd19pbmZvcyRWYXJpYWJsZXMpKV0gPC0gYygibmVjZXNzaXR5IiwiZWR1Y2F0ZWQiKQpyb3dfaW5mb3MgPC0gcm93X2luZm9zW29yZGVyKHJvd19pbmZvcyRWYXJpYWJsZXMpLCxkcm9wPUZBTFNFXQoKYW5uX2NvbF93aWRlIDwtIGRhdGEuZnJhbWUoVmFyaWFibGU9dW5pcXVlKHJvd19pbmZvcyRWYXJpYWJsZXMpKQphbm5fY29sb3JzX3dpZGUgPC0gbGlzdChWYXJpYWJsZXM9Yyhjb21tMT0iI2JkMDAyNiIsZWR1Y2F0ZWQ9Im9yYW5nZSIsIGlkMT0iI2Y2ZThjMyIsaW5zdHJ1MT0iIzM1OTc4ZiIsbmVjZXNzaXR5PSIjYjM1ODA2IixpbnRlZ3IxPSIjMzg2Y2IwIixpbnRyMT0iI2ZmZmY5OSIsb3VnaHQxPSJncmV5Iixwb3N0MT0iYmxhY2siLHByb2YxPSJwaW5rIikpCgpkaWFnKGNvdikgPC0gTkEKcGhlYXRtYXAoY292LCBtYWluID0gIkFsbCBDb250ZXh0cyIsYW5ub3RhdGlvbl9uYW1lc19yb3cgPSBGQUxTRSxjbHVzdGVyX2NvbHM9VFJVRSxjbHVzdGVyX3Jvd3M9VFJVRSxhbm5vdGF0aW9uX2NvbCA9IHJvd19pbmZvc1ssMSxkcm9wPUZBTFNFXSwgYW5ub3RhdGlvbl9yb3cgPSByb3dfaW5mb3NbLDEsZHJvcD1GQUxTRV0KLCAgYW5ub3RhdGlvbl9jb2xvcnMgPSBhbm5fY29sb3JzX3dpZGUsc2hvd19jb2xuYW1lcyA9IEZBTFNFLGJyZWFrcyA9IHNlcSgtMC42LDAuNyxsZW5ndGgub3V0ID0gNTApLHdpZHRoID0gNyxoZWlnaHQgPSA3LGNvbG9yPWNvbG9yUmFtcFBhbGV0dGUoYnJld2VyLnBhbChuID0gNywgbmFtZSA9ICJSZEJ1IikpKDUwKSkKCmBgYAoKIyMgQ29tcGFyZSBjb3JyZWxhdGlvbnMKCmBgYHtyfQpsaWJyYXJ5KEdHYWxseSkKY29tYmluZV9jb3IgPC0gbWVyZ2UoZGF0YV9jb3JfZW5nX2luX2l0YSxkYXRhX2Nvcl9lbmdfaW5fZ2VybSxhbGwgPSBUUlVFKQpjb21iaW5lX2NvcjEgPC0gbWVyZ2UoY29tYmluZV9jb3IsZGF0YV9jb3JfZ2VybV9pbl9hdSxhbGwgPSBUUlVFKQpjb21iaW5lX2NvcjIgPC0gbWVyZ2UoY29tYmluZV9jb3IxLGRhdGFfY29yX2l0YV9pbl9hdSxhbGwgPSBUUlVFKQpjb21iaW5lX2NvcjIgPC0gY29tYmluZV9jb3IyICU+JSBzZXBhcmF0ZSh2YXIxLGludG89YygiaXRlbTEiLCJ2YXJpYWJsZTEiKSxzZXA9IlsuXSIscmVtb3ZlPUZBTFNFKSAlPiUKICBzZXBhcmF0ZSh2YXIyLGludG89YygiaXRlbTIiLCJ2YXJpYWJsZTIiKSxzZXA9IlsuXSIscmVtb3ZlPUZBTFNFKSAlPiUKICB1bml0ZShncm91cCx2YXJpYWJsZTEsdmFyaWFibGUyLHNlcD0iLiIpCgpwYWlycyhjb21iaW5lX2NvcjJbLGMoImNvcl9lbmdfaW5faXRhIiwiY29yX2VuZ19pbl9nZXJtIiwiY29yX2dlcm1faW5fYXUiLCJjb3JfaXRhX2luX2F1IildKQpnZ3BhaXJzKGNvbWJpbmVfY29yMlssYygiY29yX2VuZ19pbl9pdGEiLCJjb3JfZW5nX2luX2dlcm0iLCJjb3JfZ2VybV9pbl9hdSIsImNvcl9pdGFfaW5fYXUiKV0sYWVzKGNvbG91cj1ncm91cCkpCgpgYGAKCgojIEV2YWx1YXRlIGludGVybmFsIGNvbnNpc3RlbmN5IG9mIGtub3duIGNvbnN0cnVjdHMgd2l0aCBhbHBoYQoKYGBge3J9CnNldHMgPC0gbGlzdChpZC52YXI9bGlrZXJ0X3ZhcmlhYmxlczFbZ3JlcCgiXFwuaWQxJCIsbGlrZXJ0X3ZhcmlhYmxlczEpXSwKICAgICAgICAgICAgIG91Z2h0LnZhcj1saWtlcnRfdmFyaWFibGVzMVtncmVwKCJcXC5vdWdodDEkIixsaWtlcnRfdmFyaWFibGVzMSldLAogICAgICAgICAgICAgaW50ci52YXI9bGlrZXJ0X3ZhcmlhYmxlczFbZ3JlcCgiXFwuaW50cjEkIixsaWtlcnRfdmFyaWFibGVzMSldLAogICAgICAgICAgICAgaW5zdHJ1LnZhcj1saWtlcnRfdmFyaWFibGVzMVtncmVwKCJcXC5pbnN0cnUxJCIsbGlrZXJ0X3ZhcmlhYmxlczEpXSwKICAgICAgICAgICAgIGludGVncjEudmFyPWxpa2VydF92YXJpYWJsZXMxW2dyZXAoIlxcLmludGVncjEkIixsaWtlcnRfdmFyaWFibGVzMSldLAogICAgICAgICAgICAgcHJvZi52YXI9bGlrZXJ0X3ZhcmlhYmxlczFbZ3JlcCgiXFwucHJvZjEkIixsaWtlcnRfdmFyaWFibGVzMSldLAogICAgICAgICAgICAgcG9zdC52YXI9bGlrZXJ0X3ZhcmlhYmxlczFbZ3JlcCgiXFwucG9zdDEkIixsaWtlcnRfdmFyaWFibGVzMSldLAogICAgICAgICAgICAgY29tbS52YXI9bGlrZXJ0X3ZhcmlhYmxlczFbZ3JlcCgiXFwuY29tbTEkIixsaWtlcnRfdmFyaWFibGVzMSldKQogICAgICAgICAgICAgIAoKZ2V0X2FscGhhIDwtIGZ1bmN0aW9uKGRhdGFNb3QsCiAgICAgICAgICAgICAgICAgICAgICB2YXI9c2V0cyRpZC52YXIpewogIHZhcl9hbHBoYSA8LSBhbHBoYShkYXRhTW90Wyx2YXJdKQogIGRhdGFmIDwtIGRhdGEuZnJhbWUoYWxwaGE9dmFyX2FscGhhJHRvdGFsLAogICAgICAgICAgICAgICAgICAgIGRyb3AgPSB2YXJfYWxwaGEkYWxwaGEuZHJvcCkKICByb3duYW1lcyhkYXRhZikgPC0gcm93bmFtZXModmFyX2FscGhhJGFscGhhLmRyb3ApCiAgcmV0dXJuKGRhdGFmKQp9CgojICJJdGFsaWFuIGluIEF1c3RyYWxpYSIKaXRhX2luX2F1IDwtIGRvLmNhbGwocmJpbmQsbGFwcGx5KHNldHMsZnVuY3Rpb24oeCkgewogIGdldF9hbHBoYShkYXRhPWZpbHRlcmVkX2NvbnZbZmlsdGVyZWRfY29udiRDb250ZXh0ID09ICJJdGFsaWFuIGluIEF1c3RyYWxpYSIsXSwKICAgICAgICAgICAgICAgICAgICAgIHZhcj14KX0pKQppdGFfaW5fYXUkdmFyIDwtIHNhcHBseShzdHJzcGxpdChyb3duYW1lcyhpdGFfaW5fYXUpLHNwbGl0PSJcXC4iKSxmdW5jdGlvbih4KSB4WzFdKSAKaXRhX2luX2F1JHZhci5mdWxsIDwtIHNhcHBseShzdHJzcGxpdChyb3duYW1lcyhpdGFfaW5fYXUpLHNwbGl0PSJcXC4iKSxmdW5jdGlvbih4KSB4WzNdKSAKaXRhX2luX2F1JENvbnRleHQgPC0gIkl0YWxpYW4gaW4gQXVzdHJhbGlhIgpyb3duYW1lcyhpdGFfaW5fYXUpIDwtIE5VTEwKCiMgIkdlcm1hbiBpbiBBdXN0cmFsaWEiCmdlcm1faW5fYXUgPC0gZG8uY2FsbChyYmluZCxsYXBwbHkoc2V0cyxmdW5jdGlvbih4KSB7CiAgZ2V0X2FscGhhKGRhdGE9ZmlsdGVyZWRfY29udltmaWx0ZXJlZF9jb252JENvbnRleHQgPT0gIkdlcm1hbiBpbiBBdXN0cmFsaWEiLF0sCiAgICAgICAgICAgICAgICAgICAgICB2YXI9eCl9KSkKZ2VybV9pbl9hdSR2YXIgPC0gc2FwcGx5KHN0cnNwbGl0KHJvd25hbWVzKGdlcm1faW5fYXUpLHNwbGl0PSJcXC4iKSxmdW5jdGlvbih4KSB4WzFdKSAKZ2VybV9pbl9hdSR2YXIuZnVsbCA8LSBzYXBwbHkoc3Ryc3BsaXQocm93bmFtZXMoZ2VybV9pbl9hdSksc3BsaXQ9IlxcLiIpLGZ1bmN0aW9uKHgpIHhbM10pIApnZXJtX2luX2F1JENvbnRleHQgPC0gIkdlcm1hbiBpbiBBdXN0cmFsaWEiCnJvd25hbWVzKGdlcm1faW5fYXUpIDwtIE5VTEwKCiMgIkVuZ2xpc2ggaW4gR2VybWFueSIKZW5nX2luX2dlcm0gPC0gZG8uY2FsbChyYmluZCxsYXBwbHkoc2V0c1shKG5hbWVzKHNldHMpICVpbiUgImNvbW0udmFyIildLGZ1bmN0aW9uKHgpIHsKICBnZXRfYWxwaGEoZGF0YT1maWx0ZXJlZF9jb252W2ZpbHRlcmVkX2NvbnYkQ29udGV4dCA9PSAiRW5nbGlzaCBpbiBHZXJtYW55IixdLAogICAgICAgICAgICAgICAgICAgICAgdmFyPXgpfSkpCgojIHRoZSBvbmVzIHRoYXQgbWFrZXMgaXNzdWVzCmdldF9hbHBoYShkYXRhPWZpbHRlcmVkX2NvbnZbZmlsdGVyZWRfY29udiRDb250ZXh0ID09ICJFbmdsaXNoIGluIEdlcm1hbnkiLF0sCiAgICAgICAgICAgICAgICAgICAgICB2YXI9c2V0cyRvdWdodC52YXIpCgplbmdfaW5fZ2VybSR2YXIgPC0gc2FwcGx5KHN0cnNwbGl0KHJvd25hbWVzKGVuZ19pbl9nZXJtKSxzcGxpdD0iXFwuIiksZnVuY3Rpb24oeCkgeFsxXSkgCmVuZ19pbl9nZXJtJHZhci5mdWxsIDwtIHNhcHBseShzdHJzcGxpdChyb3duYW1lcyhlbmdfaW5fZ2VybSksc3BsaXQ9IlxcLiIpLGZ1bmN0aW9uKHgpIHhbM10pIAplbmdfaW5fZ2VybSRDb250ZXh0IDwtICJFbmdsaXNoIGluIEdlcm1hbnkiCnJvd25hbWVzKGVuZ19pbl9nZXJtKSA8LSBOVUxMCgojICJFbmdsaXNoIGluIEl0YWx5IgplbmdfaW5faXRhIDwtIGRvLmNhbGwocmJpbmQsbGFwcGx5KHNldHNbIShuYW1lcyhzZXRzKSAlaW4lICJjb21tLnZhciIpXSxmdW5jdGlvbih4KSB7CiAgZ2V0X2FscGhhKGRhdGE9ZmlsdGVyZWRfY29udltmaWx0ZXJlZF9jb252JENvbnRleHQgPT0gIkVuZ2xpc2ggaW4gSXRhbHkiLF0sCiAgICAgICAgICAgICAgICAgICAgICB2YXI9eCl9KSkKZW5nX2luX2l0YSR2YXIgPC0gc2FwcGx5KHN0cnNwbGl0KHJvd25hbWVzKGVuZ19pbl9pdGEpLHNwbGl0PSJcXC4iKSxmdW5jdGlvbih4KSB4WzFdKSAKZW5nX2luX2l0YSR2YXIuZnVsbCA8LSBzYXBwbHkoc3Ryc3BsaXQocm93bmFtZXMoZW5nX2luX2l0YSksc3BsaXQ9IlxcLiIpLGZ1bmN0aW9uKHgpIHhbM10pIAplbmdfaW5faXRhJENvbnRleHQgPC0gIkVuZ2xpc2ggaW4gSXRhbHkiCnJvd25hbWVzKGVuZ19pbl9pdGEpIDwtIE5VTEwKCgojIGNvbWJpbmUKZnVsbF9hbHBoYSA8LSByYmluZChlbmdfaW5faXRhLGVuZ19pbl9nZXJtLGdlcm1faW5fYXUsaXRhX2luX2F1KQoKYGBgCgotIFBsb3QgYWxwaGEgYnkgdmFyaWFibGUKCmBgYHtyIGFscGhhX2Nocm9uYmFjaF9ieV9jb250ZXh0fQoKZnVsbF9hbHBoYSAlPiUgZ3JvdXBfYnkoQ29udGV4dCx2YXIpICU+JSAKICBzdW1tYXJpc2Uoc3QuYWxwaGEgPSB1bmlxdWUoYWxwaGEuc3RkLmFscGhhKSwKICAgICAgICAgICAgRzY9dW5pcXVlKGFscGhhLkc2LnNtYy4pKSAlPiUKICBnZ3Bsb3QoLixhZXMoeD12YXIseT1zdC5hbHBoYSxjb2xvdXI9Q29udGV4dCkpICsgZ2VvbV9wb2ludCgpICsgZ2VvbV9saW5lKGFlcyhncm91cD1Db250ZXh0KSkgKyB0aGVtZV9idygpCgpgYGAKCgpgYGB7ciBmaWcuaGVpZ2h0PTE4LGZpZy53aWR0aD0xNH0KYWxsX21lbHQgPC0gYWxsX21lbHQgJT4lIHNlcGFyYXRlKHZhcmlhYmxlLGludG89YygiaXRlbSIsInR5cGUiKSxzZXA9IlxcLiIscmVtb3ZlPUZBTFNFKQpwMT1nZ3Bsb3QoYWxsX21lbHQsYWVzKHg9dmFyaWFibGUsZmlsbD12YWx1ZSkpICsgZ2VvbV9iYXIocG9zaXRpb24gPSAic3RhY2siKSArIAogIGZhY2V0X2dyaWQoQ29udGV4dH50eXBlLHNjYWxlcyA9ICJmcmVlIikgKyBnZ3RpdGxlKCJGaWx0ZXJlZCBkYXRhc2V0IikrdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSxheGlzLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9OCkpK3RoZW1lX2J3KCkKCnAyPWdncGxvdChmdWxsX2FscGhhLGFlcyh4PXZhci5mdWxsLHk9ZHJvcC5zdGQuYWxwaGEsY29sb3VyPUNvbnRleHQpKSArIGdlb21fcG9pbnQoKSArIGdlb21fbGluZShhZXMoZ3JvdXA9Q29udGV4dCkpICsgdGhlbWVfYncoKSArIGZhY2V0X3dyYXAofnZhcixzY2FsZXM9ImZyZWUiKQoKcDQ9Z2dwbG90KGZ1bGxfYWxwaGEsYWVzKHg9dmFyLmZ1bGwseT1kcm9wLmF2ZXJhZ2Vfcixjb2xvdXI9Q29udGV4dCkpICsgZ2VvbV9wb2ludCgpICsgZ2VvbV9saW5lKGFlcyhncm91cD1Db250ZXh0KSkgKyB0aGVtZV9idygpICsgZmFjZXRfd3JhcCh+dmFyLHNjYWxlcz0iZnJlZSIpCgpwMz1mdWxsX2FscGhhICU+JSBncm91cF9ieShDb250ZXh0LHZhcikgJT4lIAogIHN1bW1hcmlzZShzdC5hbHBoYSA9IHVuaXF1ZShhbHBoYS5zdGQuYWxwaGEpLAogICAgICAgICAgICBHNj11bmlxdWUoYWxwaGEuRzYuc21jLikpICU+JQogIGdncGxvdCguLGFlcyh4PXZhcix5PXN0LmFscGhhLGNvbG91cj1Db250ZXh0KSkgKyBnZW9tX3BvaW50KCkgKyBnZW9tX2xpbmUoYWVzKGdyb3VwPUNvbnRleHQpKSArIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSksYXhpcy50ZXh0PWVsZW1lbnRfdGV4dChzaXplPTgpKSArIHRoZW1lX2J3KCkKCgpjb3dwbG90OjpwbG90X2dyaWQocDIscDMsbnJvdz0yKQoKYGBgCgo=